js中,函数的闭包、作用域跟[[Scopes]]的关系
[[Scopes]]是函數的內部屬性,是無法訪問的,但是我們可以通過Chrome的開發者工具看到它的樣子。
我們現在聲明個函數
foo
需要查看foo的原型對象才能看到[[scopes]]屬性,因為foo.prototype.constructor和foo指向同一個函數,所以點開constructor選項。
現在我們終于看到了[[Scopes]]屬性。
可以清楚的看到它是一個數組,只有一個元素Global也就是全局對象,經過我目測這個Global應該和window對象是同一個對象。
// 定義一個全局的變量
var a = 'global property'
function foo () {
console.log(a)
}
foo() // 此時會輸出global property
復制代碼
如上代碼所示,此時我們再看foo的[[Scopes]]屬性
會發現Global對象里增加了一個a屬性,這和window對象表現一致。事實上在函數foo里面執行console.log(a)的時候,變量a就是從這個Global對象內讀取的。
function outer () {
var a = 'property of outer scope'
return function inner () {
console.log(a)
}
}
var inner = outer()
inner() // 如大家所料,會輸出property of outer scope
復制代碼
此時我們再看一下inner的[[Scopes]]屬性
會發現[[Scopes]]數組的前面新添加了一個叫Closure的對象,從字面上看這不就是閉包的意思嗎,我們展開看一下
果然有我們閉包里的屬性a,其實inner函數里的console.log(a)中的a就是從設個Closure對象里面讀取的。我們再來看一個例子
function outer () {
var a = 1
function inner () {
var b = 2
return function innermost () {
console.log(a, b)
}
}
return inner()
}
var innermost = outer()
innermost() // 此時輸出的值是1 2
復制代碼
看一下innermost的[[Scopes]]屬性,如下圖
會發現在Scopes數組的開頭又增加了一個閉包,是按照從內到外的順序排列的,讓我們點開看一下
果然,這里的兩個閉包對象分別包含了innermost需要訪問的所有變量。這就是作用域鏈的概念,當一個函數被調用的時候,函數內部訪問的對象會先從函數自己的作用域內部進行查找,如果沒找到對應的變量,就會從[[Scopes]]數組的第一項閉包對象進行查找,如果還沒找到就繼續到下一個閉包對象查找,以此類推。
作者:被雨水過濾的空氣不想
鏈接:https://juejin.cn/post/6844903732669317128
來源:掘金
總結
以上是生活随笔為你收集整理的js中,函数的闭包、作用域跟[[Scopes]]的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity、Visual Studio
- 下一篇: 战锤鼠人结局是什么