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

首頁 > 編程 > JavaScript > 正文

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

2019-11-20 21:30:38
字體:
供稿:網(wǎng)友

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

JavaScript作用域

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

1. 全局作用域(Global Scope)

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

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

復(fù)制代碼 代碼如下:

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

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

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

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

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

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

2. 局部作用域(Local Scope)

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

復(fù)制代碼 代碼如下:

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

作用域鏈(Scope Chain)

在JavaScript中,函數(shù)也是對象,實際上,JavaScript里一切都是對象。函數(shù)對象和其它對象一樣,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內(nèi)部屬性。其中一個內(nèi)部屬性是[[Scope]],由ECMA-262標準第三版定義,該內(nèi)部屬性包含了函數(shù)被創(chuàng)建的作用域中對象的集合,這個集合被稱為函數(shù)的作用域鏈,它決定了哪些數(shù)據(jù)能被函數(shù)訪問。

當一個函數(shù)創(chuàng)建后,它的作用域鏈會被創(chuàng)建此函數(shù)的作用域中可訪問的數(shù)據(jù)對象填充。例如定義下面這樣一個函數(shù):

復(fù)制代碼 代碼如下:

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


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


函數(shù)add的作用域?qū)趫?zhí)行時用到。例如執(zhí)行如下代碼:

復(fù)制代碼 代碼如下:

var total = add(5,10);

執(zhí)行此函數(shù)時會創(chuàng)建一個稱為“運行期上下文(execution context)”的內(nèi)部對象,運行期上下文定義了函數(shù)執(zhí)行時的環(huán)境。每個運行期上下文都有自己的作用域鏈,用于標識符解析,當運行期上下文被創(chuàng)建時,而它的作用域鏈初始化為當前運行函數(shù)的[[Scope]]所包含的對象。

這些值按照它們出現(xiàn)在函數(shù)中的順序被復(fù)制到運行期上下文的作用域鏈中。它們共同組成了一個新的對象,叫“活動對象(activation object)”,該對象包含了函數(shù)的所有局部變量、命名參數(shù)、參數(shù)集合以及this,然后此對象會被推入作用域鏈的前端,當運行期上下文被銷毀,活動對象也隨之銷毀。新的作用域鏈如下圖所示:

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

作用域鏈和代碼優(yōu)化

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

復(fù)制代碼 代碼如下:

function changeColor(){

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

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

};



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

function changeColor(){

var doc=document;

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

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

};



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

改變作用域鏈

函數(shù)每次執(zhí)行時對應(yīng)的運行期上下文都是獨一無二的,所以多次調(diào)用同一個函數(shù)就會導(dǎo)致創(chuàng)建多個運行期上下文,當函數(shù)執(zhí)行完畢,執(zhí)行上下文會被銷毀。每一個運行期上下文都和一個作用域鏈關(guān)聯(lián)。一般情況下,在運行期上下文運行的過程中,其作用域鏈只會被 with 語句和 catch 語句影響。

with語句是對象的快捷應(yīng)用方式,用來避免書寫重復(fù)代碼。例如:

復(fù)制代碼 代碼如下:

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,看上去更高效,實際上產(chǎn)生了性能問題。

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


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

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

復(fù)制代碼 代碼如下:

try{

doSomething();

}catch(ex){

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

}


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

try{

doSomething();

}catch(ex){

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



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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
色999五月色| 少妇黄色一级片| 精品丰满少妇一区二区三区| 国产精品黄视频| 日韩久久一区| 精品sm捆绑视频| 九九九久久久| 国产亚洲精品久久777777| 黄瓜视频成人app免费| 国产精品一区二区av白丝下载| 亚洲三级久久久| 欧美裸体一区二区三区| 欧美videos另类| 亚洲日本三级| 日本精品一区二区三区四区的功能| 欧美日韩一区二区三区高清| 色狠狠一区二区三区香蕉| 欧美一级播放| 成人一区二区| 久久99青青精品免费观看| 精品夜夜嗨av一区二区三区| 最好看的日本字幕mv视频大全| 亚洲 欧美 日韩 综合| 国产激情久久久久久熟女老人av| 欧洲一区在线| 亚洲一区二区三区四区五区黄| 91在线国产福利| 亚洲精品视频一区二区三区| 久久久久久久高潮| 男人操女人的视频网站| 精品国产一区二区三区久久久狼| 午夜福利理论片在线观看| 日本高清不卡在线观看| 久久久久久久久久久国产| 中文字幕精品在线不卡| www.蜜臀av.com| jizzzz日本| 日韩国产一二三区| 国产成人精品久久| 人人干人人看| 中文字幕视频在线免费欧美日韩综合在线看| 日韩欧美视频免费在线观看| 久久99久久亚洲国产| 国产麻豆精品高清在线播放| 日韩精品在线观看免费| 午夜精品久久久久久久久久久| 色噜噜在线观看| 成人性生交大片| 中文日韩欧美| 91日韩中文字幕| 久久精品播放| 国产精品一区二区人妻喷水| 亚洲一区激情| 国产精品久久久久久久久久三级| 五月天亚洲综合情| 国产一区二区在线不卡| 新的色悠悠久久久| 国产精品嫩草在线观看| 一区二区三区日韩在线| 91在线视频在线观看| 在线视频观看你懂的| 国产精品久久久久久久久夜色| 91精品国产美女浴室洗澡无遮挡| 巨大黑人video| 91久久久久久国产精品| 国产精品粉嫩| 中文字幕99页| 日韩黄色短视频| 欧美亚洲在线| 男人天堂手机在线| 一区二区三区四区精品| 日本中文字幕精品| 欧美性在线视频| 欧美性色黄在线视频| 99在线观看视频网站| 热久久免费视频精品| 精品成人自拍视频| 激情中文字幕| 日韩久久免费电影| 日韩av免费大片| 无码 人妻 在线 视频| 黄网网址免费| 免费的av电影| 加勒比在线日本| 日本三级午夜理伦三级三| 伊人一区二区三区| 中国日韩欧美久久久久久久久| 国产免费xxx| 国产盗摄女厕一区二区三区| 91大神xh98hx在线播放| 久久一区91| 国产精品情侣呻吟对白视频| 伊人成年综合网| 最近中文字幕大全中文字幕免费| 女人被男人躁得好爽免费视频| 99re这里只有精品首页| 成人xvideos免费视频| 久久久夜精品| 无套内谢丰满少妇中文字幕| 久久久亚洲影院你懂的| 97av在线播放| 加勒比一区二区三区| 午夜精品视频在线观看一区二区| 国产亲近乱来精品视频| 久久久久久99久久久精品网站| 国产亚洲一区二区三区| 五月天亚洲激情| 国产亚洲精品美女久久久| 日韩一区av在线| 97在线观看视频免费| 一区二区三区精品久久久| 亚洲女同在线| 国产精品一品二区三区的使用体验| 国产jzjzjz丝袜老师水多| 中文字幕乱码一区| 真实原创一区二区影院| 91高清国产视频| 一区二区三区在线观看免费视频| 免费激情视频网站| 精品国产91久久久久久久妲己| 欧美精品 国产精品| 亚洲综合区在线| 今天免费高清在线观看国语| 免费看成一片| 精品无码一区二区三区在线| 亚洲精品av在线| 亚洲黄页网在线观看| 精品国产一区久久| 97caopron在线视频| 婷婷综合视频| 中文字幕一区二区三区免费视频| 91大神在线播放精品| 精品欠久久久中文字幕加勒比| 国产精品一区二区久久国产| 影院在线观看全集免费观看| 男人的天堂avav| 5g影院5g天天爽永久免费影院| 国产剧情av麻豆香蕉精品| 久久久美女艺术照精彩视频福利播放| 99视频在线免费播放| 日韩精品一区二区三区av| 国产精品xxxx| 国产专区一区二区三区| 亚洲涩涩在线| 国产精品探花视频| 五月激情综合网| 黄无遮挡免费网站| 中文在线视频观看| 在线日韩中文字幕| 成人性a激情免费视频| 97在线观看免费| 欧美视频xxx| 欧美/亚洲一区| 奇米四色7777| 米奇精品关键词| 在线黄色国产视频| 色与欲影视天天看综合网| 少妇性饥渴无码a区免费| 亚洲欧洲国产精品久久| 开心色怡人综合网站| 性一爱一乱一交一视频| 国产wwwxx| 国产精品入口| 在线欧美福利| 亚洲精品国产精品国| 韩日在线视频| 视频一区视频二区视频| 日韩午夜在线电影| 日韩美女视频免费看| 成年人网站国产| 国产精品视频地址| 天天综合久久| 麻豆一区二区三区四区精品蜜桃| 国产精品揄拍100视频| 一本色道久久综合亚洲91| 免费观看成人高| 国内久久久精品| 成人免费无码大片a毛片| 久久精品国产亚洲精品2020| www黄色在线观看视频| 天天操夜夜骑| 视频一区二区欧美| 国产精品一区二区人妻喷水| 女人高潮被爽到呻吟在线观看| 91在线精品观看| 日本一区二区三区视频在线播放| 婷婷精品进入| 欧美日韩中文另类| 黄色av一级片| 久久91超碰青草是什么| 久久99性xxx老妇胖精品| 人人插人人干| 一区二区三区免费网站| 日韩欧乱色一区二区三区在线| av女在线播放| 99re8在线精品视频免费播放| 亚洲第一中文av| 国产精品视频中文字幕91| 婷婷精品在线观看| 亚洲日本va中文字幕久久| 99草草国产熟女视频在线| 国产成人在线免费观看| 天堂av免费在线观看| 国产一区二区在线视频你懂的| 欧美/亚洲一区| 在线观看免费91| 四虎免费在线观看| 99精品美女| 精品国内自产拍在线观看| 97精品久久久午夜一区二区三区| 日韩一区二区三区四区视频| 国产youjizz在线| 成人在线免费视频观看| 美女黄色在线网站大全| 国产精品99精品一区二区三区∴| 国精产品一区二区三区| 欧洲精品毛片网站| 天天操天天操天天操天天| 韩国三级大全久久网站| 日韩有码欧美| 91精品综合视频| 偷拍亚洲精品| 国产成人精品aa毛片| av成人亚洲| 91蜜桃在线视频| 欧美艳星介绍134位艳星| 91老司机福利 在线| 色av中文字幕一区| 欧美日本免费一区二区三区| 色哟哟国产精品色哟哟| 四虎最新地址发布| 成人夜色视频网站在线观看| 欧美成人综合网站| 翔田千里一区二在线观看| 精品丝袜久久| 亚洲国产精品久久久久爰性色| 免费观看成人毛片| 一区二区三区黄| 亚洲男人影院| 中文字幕免费精品一区高清| 中文字幕成人免费视频| 久久久久国内| 日韩欧美综合在线| 在线精品亚洲| 一个人www视频在线免费观看| av手机免费看| 视频一区欧美日韩| 99久久久久成人国产免费| 2020国产精品视频| 久久久免费看| 好吊妞www.84com只有这里才有精品| 欧美精品xx| 亚洲视频在线看| 日本成人网址| gogo亚洲高清大胆美女人体| 国产精品第七影院| 日韩在线观看免费| 日韩欧美精品在线观看| 亚洲女爱视频在线| 中文字幕5566| 亚洲国产精品久久久久秋霞影院| xxxxhd欧美精品| 在线视频亚洲自拍| 亚洲视频axxx| 尤物视频在线观看视频| 成都免费高清电影| 香蕉久久国产av一区二区| 欧美成人三级视频| 91人成网站www| 3d动漫精品啪啪1区2区免费| 制服丝袜激情欧洲亚洲| 色噜噜狠狠成人中文综合| 日韩在线三区| eeuss鲁一区二区三区| 成视频免费观看在线看| 亚洲一区二区三区三州| 69夜色精品国产69乱| 尤物视频在线| 久草在线新资源| 国产精品久久久久久久免费看| 全黄一级裸体片| 一区二区国产精品| 国产a久久麻豆| 日韩精品在线观看免费| 中文字幕高清视频| 国产真实乱人偷精品人妻| 国产日本韩国在线播放| 国产视频综合在线| 羞羞的网站在线观看| 日本一区二区在线观看视频| 国产伦精品一区二区三区| 穿情趣内衣被c到高潮视频| 成人精品一二三区| 国产精品欧美日韩一区二区| 久久不卡免费视频| 日韩在线网址| 婷婷在线观看视频| 国产精品免费av一区二区| 另类成人小视频在线| 日韩电视剧免费观看网站| 狠狠操五月天| 色综合久久88| 希岛爱理av免费一区二区| 国产a∨精品一区二区三区不卡| 久热这里只有精品6| 国产精品旅馆在线| 国产精品伦理一区二区三区| 一区二区三区在线视频播放| 性欧美极品xxxx欧美一区二区| 三级毛片在线看| 在线不卡日本| 一区二区免费视频| av男人天堂网| 欧美一区二区三区系列电影| 亚洲欧美电影在线观看| 国产精品我不卡| 在线观看无遮挡| 色综合视频在线| 日本一二区视频| 99久久99热久久精品免费看| 欧美国产欧美亚州国产日韩mv天天看完整| 超碰97人人做人人爱少妇| www.综合| http://嫩草影院| 色先锋av影音| 少妇特黄a一区二区三区| 亚洲成人亚洲激情| 色999日韩国产欧美一区二区|