摘要:作用域鏈的末端始終都是全局執行環境的變量對象。作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有權訪問理解當調用時,函數被定義并作為局部變量綁定到了作用域鏈上因此函數無論在哪里調用這種綁定依然有效因此返回值為。
執行環境定義
全局執行環境定義了變量或者函數有權訪問的其他數據,每個執行環境都有一個與之相關聯的變量對象,環境中定義的所有變量和函數都保存在這個對象中。我們編寫的代碼無法訪問這個對象,但解析器會在處理數據時在后臺使用它。
執行環境的創建
在web瀏覽器中,全局執行環境被認為是window對象,因此所有全局變量和函數都是作為window對象的屬性和方法創建的。代碼載入瀏覽器時,全局執行環境被創建(當我們關閉網頁或者瀏覽器時全局執行環境才被銷毀)。
局部執行環境每個函數都有自己的執行環境,因此局部執行環境為函數對象。當函數被調用時函數的局部環境被創建(函數內的代碼執行完畢后,該環境被銷毀,同時保存在其中的所有變量和函數定義也隨之被銷毀)。
這個執行環境以及相關的變量對象是個抽象的概念,解釋如下
var a = 1; function fn(num1,num2){ var b = 2; function fnInner(){ var c = 3; alert(a + b + c); } fnInner();//fnInner調用時局部執行環境創建 } fn(4,5);//fn調用時局部執行環境創建
圖一作用域鏈
javascript函數的執行用到了作用域鏈,這個作用域鏈是函數定義的時候創建的,當定義一個函數時,它實際保存一個作用域鏈。當調用這個函數時,它創建一個新的對象來存儲它的局部變量,并將這個對象添加至保存的作用域鏈。作用域鏈的前端始終都是當前執行的代碼所在環境的變量對象。作用域鏈的末端始終都是全局執行環境的變量對象。作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有權訪問
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){return scope}; return f; } checkscope()();//local scope
理解:當調用checkscope時,函數f被定義并作為局部變量綁定到了checkscope作用域鏈上,因此函數f無論在哪里調用,這種綁定依然有效,因此返回值為local scope。
var num1 = 1; function Outer(){ var num2 = 2; console.log(num1 + num2);//3 function Inner(){ //這里可以訪問num3,num2,num1 var num3 = 3; console.log(num1 + num2 + num3);//6 } //這里可以訪問num2,Inner(),num1但不能訪問num3 Inner(); } Outer(); console.log(num1);//1,執行環境 //這里只能訪問num1
作用域鏈(向上搜索):內部環境可以通過作用域鏈訪問所有的外部環境,但外部環境不能訪問內部環境中的任何變量和函數。
var name = "Byron"; function fn(){ var name = "Csper"; console.log(name);//Casper } fn();
越往內部的環境,變量權重越高。
注意:沒有帶var關鍵字直接聲明的變量屬于全局變量如直接聲明a = 1,此時的a為全局變量。
javscript引擎在進入作用域時,會對代碼分兩輪處理。第一輪,初始化變量。第二輪,執行代碼
var a = 1; function prison (a) { console.log(a);//1 var a; console.log(a);//1 } prison(1);函數執行
函數調用進入執行環境時,首先處理arguments,初始化形參(默認值為undefined),然后初始化函數內的函數聲明,當代碼一步一步執行時再初始化函數內的變量聲明(進入環境未開始執行代碼時,值為undefined)。所以函數內的初始化順序為變量聲明,函數聲明,形參。可以從上圖圖一看出。下面我來舉個例子(整個全局環境也是函數)。
alert(typeof fn);//function,函數聲明提前 alert(typeof fn0);//undefined,變量聲明提前但未賦值 function fn(){ //函數表達式 } var fn0 = function(){ //函數定義式 } alert(typeof fn0);//function,此時變量已被賦值
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85838.html
摘要:之前一篇文章我們詳細說明了變量對象,而這里,我們將詳細說明作用域鏈。而的作用域鏈,則同時包含了這三個變量對象,所以的執行上下文可如下表示。下圖展示了閉包的作用域鏈。其中為當前的函數調用棧,為當前正在被執行的函數的作用域鏈,為當前的局部變量。 showImg(https://segmentfault.com/img/remote/1460000008329355);初學JavaScrip...
摘要:示例當一個函數創建后,它的作用域鏈會被創建此函數的作用域中可訪問的數據對象填充。每一個運行期上下文都和一個作用域鏈關聯。此時,作用域鏈中函數的所有局部變量所在的作用域對象會被推后,訪問代價變高了。 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。 作用域鏈 函數對象有一個內部屬性[...
摘要:當我將此題的作用域鏈畫出來之后,終于感覺作用域入門了。創建函數的作用域鏈,并初始化為函數的所包含的對象,即包含了的作用域鏈。 作用域 為了理解作用域,跪看了好幾篇大神的博文,終于略知一二。 1.題目 其中,看到這樣一道題(稍作修改): function factory() { var name = laruence; var intro = function(){...
摘要:變量對象作用域鏈因為變量對象在執行上下文進入執行階段時,就變成了活動對象,因此圖中使用了來表示。 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數的可見性和生命周期。在 JavaScript 中,變量的作用域有全局作用域和局部作用域兩種。JavaScript 采用詞法作用域(lexical scoping),也就是靜態作用域。 靜態作用域 函數的作用域在函數定義的時候...
摘要:變量對象作用域鏈因為變量對象在執行上下文進入執行階段時,就變成了活動對象,因此圖中使用了來表示。 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數的可見性和生命周期。在 JavaScript 中,變量的作用域有全局作用域和局部作用域兩種。JavaScript 采用詞法作用域(lexical scoping),也就是靜態作用域。 靜態作用域 函數的作用域在函數定義的時候...
閱讀 3351·2021-10-13 09:40
閱讀 2586·2021-10-08 10:17
閱讀 3989·2021-09-28 09:45
閱讀 922·2021-09-28 09:35
閱讀 1805·2019-08-30 10:51
閱讀 2898·2019-08-26 12:11
閱讀 1645·2019-08-26 10:41
閱讀 3091·2019-08-23 17:10