js的作用域鏈?zhǔn)怯僧?dāng)前執(zhí)行環(huán)境下的變量對(duì)象以及上層的執(zhí)行環(huán)境下的變量對(duì)象組成溉愁,它保證了當(dāng)前執(zhí)行環(huán)境對(duì)符合訪問(wèn)它的權(quán)限的函數(shù)以及變量的訪問(wèn)順序
以上為例子的話,他們的執(zhí)行上下文相繼被創(chuàng)建邢笙,而他們的變量對(duì)象可以這么來(lái)表示;
VO(全局){
arguments:.....
function:test()
var :....
}
VO(test){
arguments:....
function:add()
var:a
}
VO(add){
arguments:...
function:...
var:a
}
而add的作用域鏈,則同時(shí)包含了這三個(gè)變量對(duì)象裆操。所以add的執(zhí)行上下文中的作用域鏈可以這么表示:
add{
VO: ?//變量對(duì)象
scopeChain: [VO(add),VO(test),VO(global)], // 作用域鏈
this ? //this指向
}
從他們的關(guān)系可以用一個(gè)數(shù)組來(lái)表示
而數(shù)組的末端就是全局變量對(duì)象
所以作用域鏈可以用一個(gè)單方向的通道來(lái)表示,以它自己為最前端為起點(diǎn),最末端為重點(diǎn)鳖谈,
所以作用域鏈?zhǔn)怯梢幌盗凶兞繉?duì)象組成的一個(gè)單方面的一個(gè)通道,這樣我們就可以在這個(gè)單方面的通道里面訪問(wèn)上一層的函數(shù)和變量阔涉。
閉包的意思
當(dāng)函數(shù)可以記住并且訪問(wèn)當(dāng)前作用域(全局作用域除外)缆娃,即使這個(gè)函數(shù)是在當(dāng)前作用域之外執(zhí)行捷绒。
假設(shè)一個(gè)例子,一個(gè)函數(shù)???在函數(shù)???里面定義并且訪問(wèn)了函數(shù)???里面的變量贯要,那么B九四閉包暖侨。
通過(guò)閉包,我們可以在其他執(zhí)行上下文當(dāng)中崇渗,訪問(wèn)到函數(shù)的內(nèi)部變量字逗。如下例子
this
this的查找
this的查找是很多人迷茫的一點(diǎn)宅广,也似乎有很多人抱有this不穩(wěn)定這樣的看法葫掉,實(shí)在令人無(wú)語(yǔ)。this的查找可以說(shuō)是3種對(duì)象查找中最為簡(jiǎn)單的跟狱,因?yàn)槠鋵?shí)this對(duì)象的確定根本沒(méi)有一個(gè)“查找”的過(guò)程俭厚。
首先,this對(duì)象只會(huì)在一個(gè)函數(shù)中需要確定驶臊,如果是在全局域下挪挤,this永遠(yuǎn)為Global對(duì)象,在瀏覽器中通常就是window對(duì)象资铡。而在javascript中电禀,函數(shù)的調(diào)用一共有4種方式:
Function Invocation Pattern
諸如`foo()`的調(diào)用形式被稱為Function Invocation Pattern幢码,是函數(shù)最直接的使用形式笤休,注意這里的foo是作為單獨(dú)的變量出現(xiàn),而不是屬性症副。
在這種模式下店雅,foo函數(shù)體中的this永遠(yuǎn)為Global對(duì)象,在瀏覽器中就是window對(duì)象贞铣。
Method Invocation Pattern
諸如`foo.bar()`的調(diào)用形式被稱為Method Invocation Pattern闹啦,注意其特點(diǎn)是被調(diào)用的函數(shù)作為一個(gè)對(duì)象的屬性出現(xiàn),必然會(huì)有“.”或者“[]”這樣的關(guān)鍵符號(hào)辕坝。
在這種模式下窍奋,bar函數(shù)體中的this永遠(yuǎn)為“.”或“[”前的那個(gè)對(duì)象,如上例中就一定是foo對(duì)象酱畅。
Constructor Pattern
`new foo()`這種形式的調(diào)用被稱為Constructor Pattern琳袄,其關(guān)鍵字`new`就很能說(shuō)明問(wèn)題,非常容易識(shí)別纺酸。
在這種模式下窖逗,foo函數(shù)內(nèi)部的this永遠(yuǎn)是new foo()返回的對(duì)象。
Apply Pattern
`foo.call(thisObject)`和`foo.apply(thisObject)`的形式被稱為Apply Pattern餐蔬,使用了內(nèi)置的`call`和`apply`函數(shù)碎紊。
在這種模式下佑附,`call`和`apply`的第一個(gè)參數(shù)就是foo函數(shù)體內(nèi)的this,如果thisObject是`null`或`undefined`仗考,那么會(huì)變成Global對(duì)象音同。
應(yīng)用以上4種方式,確定一個(gè)函數(shù)是使用什么樣的Pattern進(jìn)行調(diào)用的痴鳄,就能很容易確定this是什么瘟斜。
另外,this是永遠(yuǎn)不會(huì)延作用域鏈或原原型鏈出現(xiàn)一個(gè)“查找”的過(guò)程的痪寻,只會(huì)在函數(shù)調(diào)用時(shí)就完全確認(rèn)螺句。?