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