分享-結合demo講解JS引擎工做原理

代碼以下:html

var x = 1;
function A(y){
   var x = 2;
   function B(z){
      console.log(x+y+z);
   }
   return B;
}
var C = A(1);
C(1); 

分析以下:函數

      階段一:全局初始化階段this

      js引擎在進入一段可執行代碼時,要完成如下三個初始化工做:spa

  1. 建立一個全局對象
  2. 構建一個執行環境棧,與此同時建立一個全局執行環境並壓入執行環境棧中
  3. 建立一個與全局執行環境相關的變量對象,此變量對象不只包含全局對象中的全部屬性,還包含全局定義的變量x和函數A。

      階段二:執行函數Acode

      當執行函數A(1)時,js引擎要完成如下三個工做:htm

  1. 建立函數A的執行環境,並將A的執行環境推入執行環境棧頂並獲取執行權限。
  2. 建立函數A的做用域鏈,js中每一個函數執行時都會建立本身的執行環境,每一個執行環境都有本身的做用域鏈,當執行環境被建立時,其做用域鏈初始化爲當前函數的scope所包含的對象,即當前函數的做用域對象,而函數的scope是在函數定義時肯定的,初始化爲函數定義時所處環境的變量對象。
  3. 建立函數A執行環境的變量對象(也叫活動對象),此對象包含函數的形參、arguments對象、this對象以及內部變量和內部函數的定義,而後將此變量對象推入函數A做用域鏈頂端。 

       階段三:執行函數B 對象

       函數A被執行之後,返回了B的引用,並賦值給了變量C,執行 C(1) 就至關於執行B(1),JS引擎須要完成如下工做:blog

  1.  建立函數B的執行環境,並將B的執行環境推入執行環境棧頂並獲取執行權限。(注意:當函數A返回後,A的執行環境就會從棧中被刪除,只留下全局執行環境)
  2. 建立函數B的做用域鏈,函數B是在函數A中定義的,函數B的做用域鏈初始化爲執行環境A的變量對象。
  3. 建立函數B執行環境的變量對象(活動對象),並將此變量對象推入函數B做用域鏈的頂端。

      

  當函數B執行「x+y+z」時,須要對x、y、z 三個標識符進行一一解析,解析過程遵照變量查找規則:先查找本身的變量對象(活動對象)中是否存在該屬性,若是存在,則中止查找並返回;若是不存在,繼續沿着其做用域鏈從頂端依次查找,直到找到爲止,若是整個做用域鏈上都未找到該變量,則返回「undefined」。作用域

       函數B的做用域鏈爲:get

       B的變量對象----->A的變量對象----->全局變量對象

       所以,變量x會在A的變量對象中找到,y也會在A的變量對象中找到,z在本身的變量對象中找到 ,結果爲2+ 1+ 1 = 4;

 

       總結:

  1. 函數的scope是在定義時肯定的。
  2. 函數的做用域鏈是在執行時肯定的。
  3. 函數執行時首先會建立執行環境,而後建立函數的做用域鏈,接着建立函數的活動對象。          

     

      參考博客地址:http://www.cnblogs.com/onepixel/p/5090799.html(強烈推薦)

相關文章
相關標籤/搜索