国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[學習筆記] JavaScript 作用域鏈

?xiaoxiao, / 2810人閱讀

摘要:全局執行環境的變量對象始終是作用域鏈中的最后一個變量對象。綜上,每個函數對應一個執行環境,每個執行環境對應一個變量對象,而多個變量對象構成了作用域鏈,如果當前執行環境是函數,那么其活動對象在作用域鏈的前端。

1.幾個概念

先說幾個概念:函數執行環境變量對象、作用域鏈、活動對象。這幾個東東之間有什么關系呢,往下看~

函數

函數大家都知道,我想說的是,js中,在函數內部有兩個特殊的對象:argumentsthis 。 arguments 是一個類數組對象,包含著傳入函數中的所有參數。 this 引用的是函數據以執行的環境對象。

執行環境

在《js高級程序設計》中,是這樣定義的:

  

執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自的行為。

這里要特別提到一個執行環境——全局執行環境。全局執行環境是最外圍的執行環境,在web瀏覽器中,全局執行環境被認為是window對象。全局執行環境會一直存在于環境棧的最底端,直到關閉網頁或者瀏覽器。
執行環境也叫執行上下文。

變量對象

《js高級程序設計》定義如下:

  

每個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都保存在這個對象中。

由上可以看出兩點:1.執行環境和變量對象是一一對應的。2.執行環境其實是一個“虛”的概念,而變量對象是實際存在的對象,能夠被解析器訪問到。不嚴謹的說,為了訪問執行環境,就創造了變量對象這個東東,通過變量對象就可以訪問執行環境中的所有變量和函數了,它倆其實是一個東西,只不過一個是虛的,一個是真實存在的。

當一個執行環境中的所有代碼執行完畢后,該執行環境被銷毀,保存在其中的所有變量和函數定義也隨之銷毀。其實是這個執行環境對應的變量對象被銷毀。發現很多地方都把執行環境和變量對象混談,大家似乎很少提到變量對象,都用 “執行環境” 這四個字替代了,把執行環境說成了一個對象,沒辦法,誰讓說的是一個東西呢。

變量對象補充

當JS執行流進入函數時,JavaScript引擎在內部創建一個對象,叫做Variable Object。
對應函數的每一個參數,在Variable Object上添加一個屬性,屬性的名字、值與參數的名字、值相同。
函數中每聲明一個變量,也會在Variable Object上添加一個屬性,名字就是變量名,因此為變量賦值就是給Variable Object對應的屬性賦值。
在函數中訪問參數或者局部變量時,就是在variable Object上搜索相應的屬性,返回其值。
一般情況下Variable Object是一個內部對象,JS代碼中無法直接訪問。

作用域鏈
  

作用域鏈的用途:保證對執行環境有權訪問的所有變量和函數的 有序 訪問。
當代碼在一個執行環境中執行時,就會創建變量對象的一個作用域鏈。

我的理解是,作用域鏈是由一個一個變量對象鏈接起來的一個鏈,整個作用域鏈構成了當前執行環境中變量和函數可訪問的范圍,即作用域。由于變量對象是按一定順序鏈接在一起的,所以就達到了對所有可訪問變量、函數有序訪問的效果。那么它們是按怎樣的順序鏈接成作用域鏈的呢?這就要說到最后一個概念——活動對象。

活動對象
  

當函數運行時就會為其創建一個活動對象,其中包含形參和函數特殊的arguments對象?;顒訉ο笾髸鰹楹瘮祱绦协h境的變量對象來使用。

回到之前的問題,作用域鏈中的變量對象是如何排序的呢?
作用域鏈的前端,始終都是當前執行的代碼所在環境的變量對象。但如果這個環境是函數,則將其活動對象作為變量對象,放在其作用域鏈的前端。作用域鏈中的下一個變量對象來自包含環境,而再下一個變量對象來自下一個包含環境……這樣一直延續到全局執行環境。全局執行環境的變量對象始終是作用域鏈中的最后一個變量對象。

為什么執行環境是函數會有這樣特殊的規定呢?
《JS權威指南》中有一句很精辟的描述:

  

JavaScript中的函數運行在它們被定義的作用域里,而不是它們被執行的作用域里。

按照之前所說,在函數定義的作用域里,當前執行環境的作用域鏈上是沒有該函數的活動對象的,為了訪問函數內部的變量、函數,所以要將其活動對象插在當前作用域鏈的前端。

2.它們之間的關系

每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。而在執行后,棧將其環境彈出,把控制權返回給之前的執行環境。

綜上,每個函數對應一個執行環境,每個執行環境對應一個變量對象,而多個變量對象構成了作用域鏈,如果當前執行環境是函數,那么其活動對象在作用域鏈的前端。

3.其他補充

JS的語法風格和 C/C++ 類似, 但作用域的實現卻和 C/C++ 不同,并非用“堆棧”方式,而是使用列表,具體過程如下(ECMA262中所述):

任何執行上下文時刻的作用域, 都是由作用域鏈(scope chain)來實現.
在執行func的定義語句的時候, 會創建一個這個函數對象的[[scope]]屬性(內部屬性,只有JS引擎可以訪問),并將這個[[scope]]屬性鏈接到定義它的作用域鏈上。
在調用func的時候, 會創建一個活動對象,然后將調用參數賦值給形參數,對于缺少的調用參數,賦值為undefined。然后將這個活動對象做為scope chain的最前端, 并將func的[[scope]]屬性所指向的,定義func時候的頂級活動對象,加入到scope chain.

參考資料

《js高級程序設計》 P73 4.2 執行環境及作用域
鳥哥:JavaScript作用域原理
JavaScript 開發進階:理解 JavaScript 作用域和作用域鏈

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91506.html

相關文章

  • 學習筆記JavaScript 閉包是怎么通過作用域鏈霸占更多內存的?

    摘要:閉包是怎么通過作用域鏈霸占更多內存的本文是作者學習高級程序設計第一小節的一點個人理解,詳細教程請參考原教材。函數執行過程創建了一個函數的活動對象,作用域鏈的最前端指向這個對象。函數執行完畢返回值后執行環境作用域鏈和活動對象一并銷毀。 JavaScript 閉包是怎么通過作用域鏈霸占更多內存的? 本文是作者學習《JavaScript 高級程序設計》7.2第一小節的一點個人理解,詳細教程請...

    HmyBmny 評論0 收藏0
  • javascript學習筆記(1)

    摘要:關于作用域實現的描述任何執行上下文時刻的作用域,都是由作用域鏈來實現的。在一個函數被定義的時候,會將它此時的作用域鏈鏈接到這個函數對象的屬性。參考資料鳥哥作用域原理理解作用域和作用域鏈阮一峰老師微博上的關于作用域的一道題 javascript作用域原理學習   在每次調用一個函數的時候,就會進入一個函數內的作用域,當從函數返回 以后,就會返回調用前的作用域。   ECMA262關于作...

    Chaz 評論0 收藏0
  • [學習筆記] JavaScript 閉包

    摘要:但是,必須強調,閉包是一個運行期概念。通過原型鏈可以實現繼承,而與閉包相關的就是作用域鏈。常理來說,一個函數執行完畢,其執行環境的作用域鏈會被銷毀。所以此時,的作用域鏈雖然銷毀了,但是其活動對象仍在內存中。 學習Javascript閉包(Closure)javascript的閉包JavaScript 閉包深入理解(closure)理解 Javascript 的閉包JavaScript ...

    sunsmell 評論0 收藏0
  • JavaScript 作用學習筆記

    摘要:每一個運行期上下文都和一個作用域鏈關聯。這個對象將被推入作用域鏈的頭部,這意味著函數的所有局部變量現在處于第二個作用域鏈對象中,因此訪問代價更高了。在代碼塊內部,函數的所有局部變量將會被放在第二個作用域鏈對象中。 參考: Javascript作用域原理 理解 JavaScript 作用域和作用域鏈 JavaScript 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數...

    趙連江 評論0 收藏0
  • JavaScript作用學習筆記

    摘要:我們再來看一下第一段代碼小紅小黑腳本出錯腳本出錯在這段代碼中變量與函數,都擁有局部作用域。作用域鏈的最前端,始終都是當前執行代碼所在的作用域的變量對象。 個人博客原址 無論什么語言中,作用域都是一個十分重要的概念,在JavaScript中也不例外,作用域定義了變量或者函數有權訪問的范圍,決定了它們各自的行為。要理解JavaScript中的作用域首先就要知道:在let出現之前,JS中變...

    jerryloveemily 評論0 收藏0

發表評論

0條評論

?xiaoxiao,

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<