首頁 >web前端 >js教程 >javascript中關於作用域鏈的詳解

javascript中關於作用域鏈的詳解

黄舟
黄舟原創
2017-09-28 11:11:341288瀏覽

這篇文章主要介紹了javascript 作用於作用域鏈的詳解的相關資料,希望透過本文能幫助到大家,理解掌握這部分內容,需要的朋友可以參考下

javascript 作用於作用域鏈的詳解

一、JavaScript作用域

任何程式設計語言都有作用域的概念,簡單的說,作用域是變數與函數的可存取範圍,即作用域控制變數與函數的可見性與生命週期。在JavaScript中,變數的作用域有全域作用域和局部作用域兩種。

全域作用域(Global Scope)

在程式碼中任何地方都能存取的物件擁有全域作用域,一般來說一下幾種情形擁有全域作用域:

(1)最外層函數和在最外層函數外定義的變數擁有全域作用域,

例如:


var authorName="Burce_zxy";
function doSomething(){
var blogName="旅行的意义zxy";
function innerSay(){alert(blogName);
}
innerSay();
}
alert(authorName); //Bruce_zxyalert(blogName); //脚本错误doSomething(); //旅行的意义zxyinnerSay() //脚本错误

(2)所有末定義直接賦值的變數自動宣告為擁有全域作用域,例如:


function doSomething()
{
var authorName="Bruce_zxy";
blogName="旅行的意义zxy";
alert(authorName);
}
alert(blogName); //旅行的意义zxyalert(authorName); //脚本错误

變數blogName擁有全域作用域,而authorName在函數外部無法存取。

(3)所有window物件的屬性擁有全域作用域

#一般情況下,window物件的內建屬性都擁有全域作用域,例如window.name 、window.location、window.top等等。

局部作用域(Local Scope)

和全域作用域相反,局部作用域一般只在固定的程式碼片段內可存取到,最常見的例如函數內部,所有在某些地方也會看到有人把這種作用域變成函數作用域,例如下列程式碼中的blogName和函數innerSay都只擁有局部作用域。


function doSomething()
{
var blogName="旅行的意义zxy";
function innerSay(){alert(blogName);
}innerSay();
}
alert(blogName);

二、作用域鏈(Scope Chain)

在JavaScript中,函數也是對象,實際上,JavaScript裡面一切都是物件。函數物件和其它物件一樣,擁有可以透過程式碼存取的屬性和一系列僅供JavaScript引擎存取的內部屬性。其中一個內部屬性是[[Scope]],由ECMA-262標準第三版定義,該內部屬性包含了函數被創建的作用域中物件的集合,這個集合被稱為函數的作用域鏈,它決定了哪些資料能被函數存取。

當一個函數建立後,它的作用域鏈會被建立此函數的作用域中可存取的資料物件填入。例如定義下面這樣一個函數:


function add(num1,num2) 
{
var sum = num1 + num2;
return sum;
}

在函數add創建時,它的作用域鏈中會填入一個全域對象,該全域對象包含了所有全域變數。如下圖所示(注意:圖片只例舉了全部變數中的一部分):


#全域變數

##函數add的作用域將會在執行時用到。例如執行以下程式碼:


var total = add(5,10);

執行此函數時會建立一個稱為「執行期上下文(execution context)」的內部對象,運行期間上下文定義了函數執行時的環境。每個運行期上下文都有自己的作用域鏈,用於標識符解析,當運行期上下文被創建時,而它的作用域鏈初始化為當前運行函數的[[Scope]]所包含的對象。這些值會依照它們出現在函數中的順序被複製到運行期上下文的作用域鏈中。它們共同組成了一個新的對象,叫“活動對象(activation object)”,該對象包含了函數的所有局部變量、命名參數、參數集合以及this,然後此對象會被推入作用域鏈的前端,當運行期上下文被銷毀,活動物件也隨之銷毀。新的作用域鏈如下圖所示:


新作用域鏈

在函數執行過程中,沒遇到一個變量,都會經歷一次標識符解析過程以決定從哪裡取得和儲存資料。過程從作用域鏈頭部,也就是從活動對象開始搜索,查找同名的標識符,如果找到了就使用這個標識符對應的變量,如果沒找到繼續搜索作用域鏈中的下一個對象,如果搜尋完所有物件都未找到,則認為該標識符未定義。函數執行過程中,每個標識符都要經歷這樣的搜尋過程。

以上是javascript中關於作用域鏈的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn