亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript作用域與作用域鏈深入解析

2019-11-20 21:30:38
字體:
來源:轉載
供稿:網友

作用域是JavaScript最重要的概念之一,想要學好JavaScript就需要理解JavaScript作用域和作用域鏈的工作原理。今天這篇文章對JavaScript作用域和作用域鏈作簡單的介紹,希望能幫助大家更好的學習JavaScript。

JavaScript作用域

任何程序設計語言都有作用域的概念,簡單的說,作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。

1. 全局作用域(Global Scope)

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

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

復制代碼 代碼如下:

var authorName="山邊小溪";
function doSomething(){
var blogName="";
function innerSay(){
alert(blogName);
}
innerSay();
}
alert(authorName); //山邊小溪
alert(blogName); //腳本錯誤
doSomething(); //
innerSay() //腳本錯誤 

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

function doSomething(){
var authorName="山邊小溪";
blogName="";
alert(authorName);
}
alert(blogName); //
alert(authorName); //腳本錯誤 

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

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

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

2. 局部作用域(Local Scope)

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

復制代碼 代碼如下:

function doSomething(){
var blogName="";
function innerSay(){
alert(blogName);
}
innerSay();
}
alert(blogName); //腳本錯誤
innerSay(); //腳本錯誤 

作用域鏈(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,然后此對象會被推入作用域鏈的前端,當運行期上下文被銷毀,活動對象也隨之銷毀。新的作用域鏈如下圖所示:

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

作用域鏈和代碼優化

從作用域鏈的結構可以看出,在運行期上下文的作用域鏈中,標識符所在的位置越深,讀寫速度就會越慢。如上圖所示,因為全局變量總是存在于運行期上下文作用域鏈的最末端,因此在標識符解析的時候,查找全局變量是最慢的。所以,在編寫代碼的時候應盡量少使用全局變量,盡可能使用局部變量。一個好的經驗法則是:如果一個跨作用域的對象被引用了一次以上,則先把它存儲到局部變量里再使用。例如下面的代碼:

復制代碼 代碼如下:

function changeColor(){

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

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

};



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

function changeColor(){

var doc=document;

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

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

};



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

改變作用域鏈

函數每次執行時對應的運行期上下文都是獨一無二的,所以多次調用同一個函數就會導致創建多個運行期上下文,當函數執行完畢,執行上下文會被銷毀。每一個運行期上下文都和一個作用域鏈關聯。一般情況下,在運行期上下文運行的過程中,其作用域鏈只會被 with 語句和 catch 語句影響。

with語句是對象的快捷應用方式,用來避免書寫重復代碼。例如:

復制代碼 代碼如下:

function initUI(){

with(document){

var bd=body,

links=getElementsByTagName("a"),

i=0,

len=links.length;

while(i < len){

update(links[i++]);

}

getElementById("btnInit").onclick=function(){

doSomething();

};

}



這里使用width語句來避免多次書寫document,看上去更高效,實際上產生了性能問題。

當代碼運行到with語句時,運行期上下文的作用域鏈臨時被改變了。一個新的可變對象被創建,它包含了參數指定的對象的所有屬性。這個對象將被推入作用域鏈的頭部,這意味著函數的所有局部變量現在處于第二個作用域鏈對象中,因此訪問代價更高了。如下圖所示:


因此在程序中應避免使用with語句,在這個例子中,只要簡單的把document存儲在一個局部變量中就可以提升性能。

另外一個會改變作用域鏈的是try-catch語句中的catch語句。當try代碼塊中發生錯誤時,執行過程會跳轉到catch語句,然后把異常對象推入一個可變對象并置于作用域的頭部。在catch代碼塊內部,函數的所有局部變量將會被放在第二個作用域鏈對象中。示例代碼:

復制代碼 代碼如下:

try{

doSomething();

}catch(ex){

alert(ex.message); //作用域鏈在此處改變

}


請注意,一旦catch語句執行完畢,作用域鏈機會返回到之前的狀態。try-catch語句在代碼調試和異常處理中非常有用,因此不建議完全避免。你可以通過優化代碼來減少catch語句對性能的影響。一個很好的模式是將錯誤委托給一個函數處理,例如:
復制代碼 代碼如下:

try{

doSomething();

}catch(ex){

handleError(ex); //委托給處理器方法



優化后的代碼,handleError方法是catch子句中唯一執行的代碼。該函數接收異常對象作為參數,這樣你可以更加靈活和統一的處理錯誤。由于只執行一條語句,且沒有局部變量的訪問,作用域鏈的臨時改變就不會影響代碼性能了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
y97精品国产97久久久久久| 日韩精品在线视频| 亚洲精品乱码久久久久久按摩观| 久久久久久97| 91免费版网站入口| 一个人www欧美| 国产视频精品免费播放| 亚洲尤物视频网| 国产91色在线免费| 亚洲一区二区黄| 国产精品视频免费观看www| 伦伦影院午夜日韩欧美限制| 91久久久久久久久久久| 国产精品露脸自拍| 91精品国产91久久久久久不卡| 中文字幕在线看视频国产欧美| 免费99精品国产自在在线| 亚洲精品aⅴ中文字幕乱码| 亚洲综合精品一区二区| 国产精品www色诱视频| 欧美视频二区36p| 中文字幕日韩精品有码视频| xvideos成人免费中文版| 亚洲直播在线一区| 精品久久久久久中文字幕大豆网| 狠狠躁18三区二区一区| 日韩免费黄色av| 中文字幕一区二区三区电影| 国产精品视频一区国模私拍| 国产成人福利夜色影视| 精品成人国产在线观看男人呻吟| 色一情一乱一区二区| 中文字幕少妇一区二区三区| 91久久精品美女高潮| 国产精品久久久久久久电影| 亚洲电影免费观看高清完整版| 91精品久久久久久综合乱菊| 国产精品久久网| 国产999精品久久久影片官网| 欧美成人午夜激情| 狠狠躁18三区二区一区| 美女撒尿一区二区三区| 中文字幕亚洲第一| 久久精品久久久久久国产 免费| 亚洲国产欧美一区| 国产一区二区三区在线观看视频| 亚洲人成在线免费观看| 亚洲在线视频福利| 欧美精品九九久久| 欧美亚洲成人免费| 欧美韩国理论所午夜片917电影| 少妇高潮 亚洲精品| 亚洲女性裸体视频| 91精品国产91久久久久福利| 国产精品va在线播放| 欧美在线亚洲在线| 亚洲综合日韩在线| 欧美电影在线观看| 欧美在线视频免费播放| 午夜剧场成人观在线视频免费观看| 国产a∨精品一区二区三区不卡| 色悠悠久久久久| 日韩国产欧美区| 91精品91久久久久久| 亚洲情综合五月天| 91免费精品国偷自产在线| 九九视频直播综合网| 国内精品久久影院| 亚洲精品国产精品国自产观看浪潮| 成人午夜激情网| 欧美大胆在线视频| 在线播放国产精品| 成人有码视频在线播放| 性欧美视频videos6一9| 欧美日韩中文在线观看| 欧美在线视频一区| 国产精品夜色7777狼人| 久久久久中文字幕| 国产精品成人av性教育| 国产欧美一区二区三区视频| 九九热这里只有精品6| 日本精品视频在线观看| 国产原创欧美精品| 一区二区三区四区精品| 欧美丰满少妇xxxx| 欧美日韩性生活视频| 亚洲欧美精品一区| 午夜欧美不卡精品aaaaa| 亚洲人午夜精品| 精品欧美国产一区二区三区| 亚洲一区二区福利| 国产精品综合久久久| 亚洲精品久久久久久久久| 欧美在线视频在线播放完整版免费观看| 国产精品丝袜白浆摸在线| 91高潮在线观看| 日韩精品在线免费观看视频| 久久成人一区二区| 日韩一区在线视频| 亚洲精品国产精品自产a区红杏吧| 欧美高清videos高潮hd| 亚洲激情电影中文字幕| 久久九九全国免费精品观看| 欧美日韩美女在线观看| 久久久久久久久久久人体| 日韩欧美在线一区| 亚洲国产精品va| 欧美精品18videos性欧| 91在线无精精品一区二区| 日韩欧美极品在线观看| 亚洲色图13p| 色综合色综合网色综合| 尤物九九久久国产精品的特点| 95av在线视频| 亚洲第一福利在线观看| 国产精品高潮视频| 亚洲摸下面视频| 国模gogo一区二区大胆私拍| 亚洲精品国精品久久99热一| 欧美又大又硬又粗bbbbb| 亚洲精品动漫100p| 精品国产老师黑色丝袜高跟鞋| 国产精品日日做人人爱| 另类色图亚洲色图| 91高清视频在线免费观看| 伊人伊成久久人综合网站| 国产aⅴ夜夜欢一区二区三区| 欧美性少妇18aaaa视频| 91国产视频在线| 中文字幕亚洲情99在线| 久久青草福利网站| 国产精品羞羞答答| 久久九九有精品国产23| 久久精品青青大伊人av| 91久久国产精品91久久性色| 久久久精品久久| 成人免费网站在线看| 91精品国产自产在线| 亚洲另类图片色| 亚洲精品一区二区三区婷婷月| 国内精品400部情侣激情| 国产精品稀缺呦系列在线| 91中文字幕一区| 亚洲天堂久久av| 亚洲美女在线视频| 国产在线拍揄自揄视频不卡99| 久久综合五月天| 91禁国产网站| 国产精品九九久久久久久久| 国产视频亚洲精品| 97视频在线观看网址| 亚洲www永久成人夜色| 久久91亚洲精品中文字幕奶水| 久久影院资源站| 国产精品成人观看视频国产奇米| 欧美性受xxxx黑人猛交| 国产精品免费电影| 国产+成+人+亚洲欧洲| 亚洲第一综合天堂另类专| 美日韩精品免费观看视频| 成人久久一区二区| 伊人亚洲福利一区二区三区| 中文字幕精品www乱入免费视频| 欧美成人在线网站|