如何理解js中的作用域與作用域鏈

大家好,我是IT修真院武漢分院第10期學員余佳貝,一枚正直善良的web程序員。

今天給大家分享一下,修真院官網(wǎng)js任務4,深度思考中的知識點——如何理解js中的作用域與作用域鏈

一.背景介紹

什么是作用域呢,簡單的說,作用域就是變量與函數(shù)的可訪問范圍,即作用域控制著變量與函數(shù)的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。

二.知識剖析

1.全局作用域(Global Scope)

在代碼中任何地方都能訪問到的對象擁有全局作用域,一般來說一下幾種情形擁有全局作用域:

(1)在函數(shù)外面定義的變量擁有全局作用域,例如:

varauthorName ="山邊小溪";functiondoSomething(){

alert(authorName);

}

doSomething();

(2)所有末定義直接賦值的變量自動聲明為擁有全局作用域,例如:

functiondoSomething(){varauthorName="山邊小溪";

blogName="夢想天空";

alert(authorName);

}

doSomething();//山邊小溪

alert(blogName);//夢想天空

alert(authorName);//腳本錯誤

變量blogName擁有全局作用域,而authorName在函數(shù)外部無法訪問到。

(3)所有window對象的屬性擁有全局作用域

一般情況下,window對象的內(nèi)置屬性都都擁有全局作用域,例如window.name、window.top等等。

varsite ='baidu.com';functiongetSite(){

alert(this.site);

}

alert(window.site);// 'baidu.com'

getSite();// 'baidu.com'

window.getSite();// 'baidu.com'

在上面示例中,site變量和getSite()方法沒有指定上級對象,所在二者會被添加到window全局對象,所以直接訪問二者與通過window訪問本質(zhì)相同(如,直接訪問getSite()與使用window.getSite()訪問一樣)。

1. 局部作用域(Local Scope)

和全局作用域相反,局部作用域一般只在固定的代碼片段內(nèi)可訪問到,最常見的例如函數(shù)內(nèi)部,所有在一些地方也會看到有人把這種作用域成為函數(shù)作用域

例如下列代碼中的bName和函數(shù)innerSay都只擁有局部作用域:

functiondoSomething(){varbName="雙擊66";functioninnerSay(){

alert(bName);

}

innerSay();

}

alert(bName);//腳本錯誤

innerSay();//腳本錯誤

作用域鏈(Scope Chain)

說完了作用域我們就可以接著來聊聊作用域鏈(Scope Chain)這個概念了.作用域鏈就是由多個作用域組成的 在JS中,函數(shù)的可以允許嵌套的。即,在一個函數(shù)的內(nèi)部聲明另一個函數(shù).類似這樣:

functionA(){

????vara=1;

????functionB(){//在A函數(shù)內(nèi)部,聲明了函數(shù)B,這就是所謂的函數(shù)嵌套。

????????varb=2;

????}

}

對于A來說,A函數(shù)在執(zhí)行的時候,會創(chuàng)建其A函數(shù)的作用域, 那么函數(shù)B在創(chuàng)建的時候,會引用A的作用域,類似下面這樣

函數(shù)B在執(zhí)行的時候,其作用域類似于下面這樣:

從上面的兩幅圖中可以看出,函數(shù)B在執(zhí)行的時候,是會引用函數(shù)A的作用域的。所以,像這種函數(shù)作用域的嵌套就組成了所謂的函數(shù)作用域鏈。當在自身作用域內(nèi)找不到該變量的時候,會沿著作用域鏈逐步向上查找,若在全局作用域內(nèi)部仍找不到該變量,則會拋出異常。

三.常見問題

如何更加直觀的體現(xiàn)作用域鏈

四.解決方案

五.編碼實戰(zhàn)

六.拓展思考

如何運用作用域鏈的知識進行性能優(yōu)化

其實作用域鏈就是JS引擎查詢數(shù)據(jù)的一個鏈表,后定義的覆蓋先定義的,查詢不到定義的數(shù)據(jù)就往深一層查詢,一直到全局作用域為止 但是越往內(nèi)層延伸,讀寫速度就會越慢,查找全局變量是最慢的。所以,在編寫代碼的時候應盡量少使用全局變量,盡可能使用局部變量。 如果一個跨作用域的對象被引用了一次以上,則先把它存儲到局部變量里再使用。例如下面的代碼:

functionchangeColor(){document.getElementById("btnChange").onclick=function(){document.getElementById("targetCanvas").style.backgroundColor="red";

};

}

這個函數(shù)引用了兩次全局變量document,查找該變量必須遍歷整個作用域鏈,直到最后在全局對象中才能找到。這段代碼可以重寫如下:

functionchangeColor(){vardoc=document;

doc.getElementById("btnChange").onclick=function(){

doc.getElementById("targetCanvas").style.backgroundColor="red";

};

}

這段代碼比較簡單,但是如果程序中有大量的全局變量被從反復訪問,那么重寫后的代碼性能會有顯著改善。

七.參考文獻

八.更多討論

PPT



undefined_騰訊視頻
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容