1. 程式人生 > >javascript作用域鏈理解

javascript作用域鏈理解

sco 執行上下文 變量提升 返回 結構圖 活動 ren 產生 內部

執行上下文(Execution context,簡稱EC) 概念 每當控制器到達ECMAScript可執行代碼的時候,就進入了一個執行上下文。 javascript中,EC分為三種: 全局級別的代碼(全局執行上下文) 函數級別的代碼(函數執行性上下文) Eval的代碼(eval執行上下文) 執行上下文對象包括三個關鍵屬性,可能有其他自定義屬性。 VO(Variable object), 變量對象 或者 AO(activation object),活動對象,是個字典,包括函數arguments對象,形參,內部變量,函數聲明 Scope chain,作用域鏈對象,包括當前作用域的vo和所有父級作用域的vo。 this對象,Context object,上下文對象。 技術分享
作用域鏈的鏈式結構 作用域鏈的鏈式結構,是AO有個父級變量對象的引用,用 __parent__內部屬性指代。則通過對父級的應用形成一種 鏈式結構,如下圖 作用域鏈結構圖片 技術分享 執行上下文的執行過程 EC的建立分為兩個階段:進入執行上下文階段和代碼執行階段 1.進入上下文階段 發生在函數調用時,在執行具體代碼之前。做如下三件事: 創建作用域鏈(Scope Chain) 創建變量對象 設置this對象的值,this對象的值取決於對象的調用者,caller和調用方式決定了this的值。 變量對象中的變量值如下: 根據函數參數創建並初始化arguments對象 函數聲明創建屬性,關聯具體函數 變量初始化為undefined(所謂變量提升) 同名覆蓋原則 函數聲明與參數同名 函數聲明覆蓋參數 變量與函數聲明或參數同名,變量賦值前其有效 2.代碼執行階段
變量賦值 解釋執行其他代碼 執行上下文的創建會形成一個棧,新創建的執行上下文入棧,執行完畢則出棧。 程序執行時,首先進入全局執行上下文,Global Context入棧, 在全局中有函數調用,則會進入函數執行上下文,函數執行上下文入棧 執行上下文棧 圖片 技術分享 閉包

定義

包含自由變量的函數就是閉包(自由變量指不是函數參數,也不是函數內部變量的變量,即外部變量)
該函數通常為內部函數,被返回,外部可以引用該函數,通過其訪問自由變量。

閉包的用途

1. 讀取函數內部的變量
2. 讓變量的值始終保持在內存中,比如循環註冊事件,在事件中訪問循環變量,需要用閉包來保持循環變量
3. IIFE(立即調用的函數表達式),在引用了外部變量的時候,也會形成閉包,形成一個獨立的作用域,防止變量汙染

閉包註意點

1. 閉包會使得父級作用域的變量都被保存在內存中,內存消耗大,在IE中可能會導致內存泄漏。少用閉包,或者將不使用的局部變量全部刪除
2. 父級作用域的變量是共享,一個閉包修改了變量的值,其他閉包的值獲取的值也會發生變化,容易產生錯誤

javascript作用域鏈理解