javascript 作用于作用域鏈的詳解
javascript 作用于作用域鏈的詳解
一、JavaScript作用域
任何程序設(shè)計(jì)語言都有作用域的概念,簡單的說,作用域就是變量與函數(shù)的可訪問范圍,即作用域控制著變量與函數(shù)的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。
全局作用域(Global Scope)
在代碼中任何地方都能訪問到的對象擁有全局作用域,一般來說一下幾種情形擁有全局作用域:
(1)最外層函數(shù)和在最外層函數(shù)外面定義的變量擁有全局作用域,
例如:
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在函數(shù)外部無法訪問到。
(3)所有window對象的屬性擁有全局作用域
一般情況下,window對象的內(nèi)置屬性都都擁有全局作用域,例如window.name、window.location、window.top等等。
局部作用域(Local Scope)
和全局作用域相反,局部作用域一般只在固定的代碼片段內(nèi)可訪問到,最常見的例如函數(shù)內(nèi)部,所有在一些地方也會看到有人把這種作用域成為函數(shù)作用域,例如下列代碼中的blogName和函數(shù)innerSay都只擁有局部作用域。
function doSomething() { var blogName="旅行的意義zxy"; function innerSay(){alert(blogName); }innerSay(); } alert(blogName);
二、作用域鏈(Scope Chain)
在JavaScript中,函數(shù)也是對象,實(shí)際上,JavaScript里一切都是對象。函數(shù)對象和其它對象一樣,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內(nèi)部屬性。其中一個內(nèi)部屬性是[[Scope]],由ECMA-262標(biāo)準(zhǔn)第三版定義,該內(nèi)部屬性包含了函數(shù)被創(chuàng)建的作用域中對象的集合,這個集合被稱為函數(shù)的作用域鏈,它決定了哪些數(shù)據(jù)能被函數(shù)訪問。
當(dāng)一個函數(shù)創(chuàng)建后,它的作用域鏈會被創(chuàng)建此函數(shù)的作用域中可訪問的數(shù)據(jù)對象填充。例如定義下面這樣一個函數(shù):
function add(num1,num2) { var sum = num1 + num2; return sum; }
在函數(shù)add創(chuàng)建時,它的作用域鏈中會填入一個全局對象,該全局對象包含了所有全局變量。如下圖所示(注意:圖片只例舉了全部變量中的一部分):
全局變量
函數(shù)add的作用域?qū)趫?zhí)行時用到。例如執(zhí)行如下代碼:
var total = add(5,10);
執(zhí)行此函數(shù)時會創(chuàng)建一個稱為“運(yùn)行期上下文(execution context)”的內(nèi)部對象,運(yùn)行期上下文定義了函數(shù)執(zhí)行時的環(huán)境。每個運(yùn)行期上下文都有自己的作用域鏈,用于標(biāo)識符解析,當(dāng)運(yùn)行期上下文被創(chuàng)建時,而它的作用域鏈初始化為當(dāng)前運(yùn)行函數(shù)的[[Scope]]所包含的對象。這些值按照它們出現(xiàn)在函數(shù)中的順序被復(fù)制到運(yùn)行期上下文的作用域鏈中。它們共同組成了一個新的對象,叫“活動對象(activation object)”,該對象包含了函數(shù)的所有局部變量、命名參數(shù)、參數(shù)集合以及this,然后此對象會被推入作用域鏈的前端,當(dāng)運(yùn)行期上下文被銷毀,活動對象也隨之銷毀。新的作用域鏈如下圖所示:
新作用域鏈
在函數(shù)執(zhí)行過程中,沒遇到一個變量,都會經(jīng)歷一次標(biāo)識符解析過程以決定從哪里獲取和存儲數(shù)據(jù)。該過程從作用域鏈頭部,也就是從活動對象開始搜索,查找同名的標(biāo)識符,如果找到了就使用這個標(biāo)識符對應(yīng)的變量,如果沒找到繼續(xù)搜索作用域鏈中的下一個對象,如果搜索完所有對象都未找到,則認(rèn)為該標(biāo)識符未定義。函數(shù)執(zhí)行過程中,每個標(biāo)識符都要經(jīng)歷這樣的搜索過程。
如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
關(guān)于IE瀏覽器以及Firefox下的javascript冒泡事件的響應(yīng)層級
原來是由于IE瀏覽器以及Firefox對于冒泡型事件的支持層次不同造成的。(如對冒泡事件不是很了解可先查詢相關(guān)資料)2010-10-10Bootstrap每天必學(xué)之輪播(Carousel)插件
Bootstrap每天必須之輪播(Carousel)插件,Bootstrap 輪播(Carousel)插件是一種靈活的響應(yīng)式的向站點(diǎn)添加滑塊的方式,感興趣的小伙伴們可以參考一下2016-04-04用JS實(shí)現(xiàn)一個頁面多個css樣式實(shí)現(xiàn)
在Hello,Yang中看見的一篇文章,感覺很有用,轉(zhuǎn)來這里……2008-05-05html5+CSS 實(shí)現(xiàn)禁止IOS長按復(fù)制粘貼功能
因?yàn)樵谝苿佣薃PP需要實(shí)現(xiàn)長按執(zhí)行別的事件,但是在iOS系統(tǒng)有默認(rèn)的長按選擇復(fù)制粘貼。禁止在網(wǎng)上找了很多資料,下面小編給大家分享解決方案,一起看看吧2016-12-12Three.js基礎(chǔ)學(xué)習(xí)之場景對象
這篇文章主要給大家介紹了Three.js基礎(chǔ)學(xué)習(xí)之場景對象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用three.js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。2017-09-09xmlplus組件設(shè)計(jì)系列之分隔框(DividedBox)(8)
xmlplus 是一個JavaScript框架,用于快速開發(fā)前后端項(xiàng)目。這篇文章主要介紹了xmlplus布局類組件之分隔框,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05JS開發(fā)中基本數(shù)據(jù)類型具體有哪幾種
JS的數(shù)據(jù)類型包括基本數(shù)據(jù)類型、復(fù)雜數(shù)據(jù)類型和特殊數(shù)據(jù)類型,今天我們主要先講解一下基本數(shù)據(jù)類型。感興趣的朋友一起看看吧2017-10-10關(guān)于js函數(shù)解釋(包括內(nèi)嵌,對象等)
下面小編就為大家?guī)硪黄P(guān)于js函數(shù)解釋(包括內(nèi)嵌,對象等) 。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11