執行環境、做用域、做用域鏈、調用對象、閉包

 

 

執行環境 :  每調用一個函數時(執行函數時),系統會爲該函數建立一個封閉的局部的運行環境,即該函數的執行環境。函數老是在本身的執行環境中執行,如讀寫局部變量、函數參數、運行內部邏輯。建立執行環境的過程包含了建立函數的做用域,函數也是在本身的做用域下執行的。從另外一個角度說,每一個函數執行環境都有一個做用域鏈,子函數的做用域鏈包括它的父函數的做用域鏈。關於做用域、做用域鏈請看下面。閉包

  做用域、做用域鏈、調用對象:   函數做用域分爲詞法做用域和動態做用域。   詞法做用域是函數定義時的做用域,即靜態做用域。當一個函數定義時,他的詞法做用域就肯定了,詞法做用域說明的是在函數結構的嵌套關係下,函數做用的範圍。這個時候也就造成了該函數的做用域鏈。做用域鏈就是把這些具備嵌套層級關係的做用域串聯起來。函數的內部[[scope]]屬性指向了該做用域鏈。   動態做用域是函數調用執行時的做用域。當一個函數被調用時,首先將函數內部[[scope]]屬性指向了函數的做用域鏈,而後會建立一個調用對象,並用該調用對象記錄函數參數和函數的局部變量,將其置於做用域鏈頂部。動態做用域就是經過把該調用對象加到做用域鏈的頂部來建立的,此時的[[scope]]除了具備定義時的做用域鏈,還具備了調用時建立的調用對象。換句話說,執行環境下的做用域等於該函數定義時就肯定的做用域鏈加上該函數剛剛建立的調用對象,從而也造成了新的做用域鏈。因此說是動態的做用域,而且做用域鏈也隨之發生了變化。再看這裏的做用域,實際上是一個對象鏈,這些對象就是函數調用時建立的調用對象,以及他上面一層層的調用對象直到最上層的全局對象。    譬如全局環境下的函數A內嵌套了一個函數B,則該函數B的做用域鏈就是:函數B的做用域—>函數A的做用域—>全局window的做用域。當函數B調用時,尋找某標識符,會按函數B的做用域—>函數A的做用域—>全局window的做用域去尋找,其實是按函數B的調用對象—>函數A的調用對象—>全局對象這個順序去尋找的。也就是說當函數調用時,函數的做用域鏈其實是調用對象鏈。函數

  閉包 :  在動態執行環境中,數據實時地發生變化,爲了保持這些非持久型變量的值,咱們用閉包這種載體來存儲這些動態數據(看完下面的應用就會很好的體會這句話)。閉包的定義:所謂「閉包」,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(一般是一個函數),於是這些變量也是該表達式的一部分。   閉包就是嵌套在函數裏面的內部函數,而且該內部函數能夠訪問外部函數中聲明的全部局部變量、參數和其餘內部函數。當該內部函數在外部函數外被調用,就生成了閉包。(實際上任何函數都是全局做用域的內部函數,都能訪問全局變量,因此都是window的閉包) 對象

相關文章
相關標籤/搜索