js關(guān)于作用域鏈以及閉包的理解

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)部變量。如下例子


我們通過(guò)函數(shù)bar訪問(wèn)到了函數(shù)foo中的變量。

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)用形式被稱(chēng)為Function Invocation Pattern,是函數(shù)最直接的使用形式,注意這里的foo是作為單獨(dú)的變量出現(xiàn),而不是屬性。

在這種模式下,foo函數(shù)體中的this永遠(yuǎn)為Global對(duì)象,在瀏覽器中就是window對(duì)象。

Method Invocation Pattern

諸如`foo.bar()`的調(diào)用形式被稱(chēng)為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)用被稱(chēng)為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)`的形式被稱(chēng)為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)。?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 對(duì)于js中的閉包,無(wú)論是老司機(jī)還是小白,我想,見(jiàn)得不能再多了,然而有時(shí)三言兩語(yǔ)卻很難說(shuō)得明白,反正在我初學(xué)時(shí)...
    itclanCoder閱讀 4,295評(píng)論 1 11
  • 函數(shù)申明: 函數(shù)表達(dá)式: 遞歸 閉包 閉包是有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量函數(shù)。 即使函數(shù)中的匿名函數(shù)被返回了,...
    IT男的成長(zhǎng)記錄閱讀 206評(píng)論 0 0
  • 繼承 一、混入式繼承 二、原型繼承 利用原型中的成員可以被和其相關(guān)的對(duì)象共享這一特性,可以實(shí)現(xiàn)繼承,這種實(shí)現(xiàn)繼承的...
    magic_pill閱讀 1,126評(píng)論 0 3
  • 來(lái)源:仗劍走天涯! 關(guān)于javascript的作用域的一些總結(jié),主要參考以上文章,加上自己的整理的理解。 近日對(duì)j...
    Michael_林閱讀 1,020評(píng)論 0 1
  • 先來(lái)說(shuō)說(shuō)昨天為啥沒(méi)寫(xiě)吧!拖著疲憊的身軀,把娃安頓睡下之后就埋頭于手抄報(bào)的制作中了…沒(méi)錯(cuò),一張四開(kāi)紙大小的手抄報(bào),“...
    Daisy1982閱讀 180評(píng)論 1 1

友情鏈接更多精彩內(nèi)容