成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

理解JavaScript中的作用域和作用域鏈

XanaHopper / 3122人閱讀

摘要:示例當一個函數(shù)創(chuàng)建后,它的作用域鏈會被創(chuàng)建此函數(shù)的作用域中可訪問的數(shù)據(jù)對象填充。每一個運行期上下文都和一個作用域鏈關(guān)聯(lián)。此時,作用域鏈中函數(shù)的所有局部變量所在的作用域?qū)ο髸煌坪?,訪問代價變高了。

作用域

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

作用域鏈

函數(shù)對象有一個內(nèi)部屬性[[Scope]],包含了函數(shù)被創(chuàng)建后的作用域中對象的集合,
這個集合被稱為函數(shù)的作用域鏈,它決定了哪些數(shù)據(jù)能被函數(shù)訪問。
示例:
當一個函數(shù)創(chuàng)建后,它的作用域鏈會被創(chuàng)建此函數(shù)的作用域中可訪問的數(shù)據(jù)對象填充。

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

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

執(zhí)行add函數(shù)時會創(chuàng)建一個稱為“運行期上下文(execution context)”的內(nèi)部對象,運行期上下文定義了函數(shù)執(zhí)行時的環(huán)境。
每個運行期上下文都有自己的作用域鏈,用于標識符解析。
當運行期上下文被創(chuàng)建時,而它的作用域鏈初始化為當前運行函數(shù)的[[Scope]]所包含的對象,這些值按照它們出現(xiàn)在函數(shù)中的順序被復制到運行期上下文的作用域鏈中。
它們共同組成了一個新的對象,叫“活動對象(activation object)”,該對象包含了函數(shù)的所有局部變量、命名參數(shù)、參數(shù)集合以及this,然后此對象會被推入作用域鏈的前端,當運行期上下文被銷毀,活動對象也隨之銷毀。新的作用域鏈如下圖所示:

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

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

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

改變作用域鏈

函數(shù)每次執(zhí)行時對應的運行期上下文都是獨一無二的,所以多次調(diào)用同一個函數(shù)就會導致創(chuàng)建多個運行期上下文,當函數(shù)執(zhí)行完畢,執(zhí)行上下文會被銷毀。每一個運行期上下文都和一個作用域鏈關(guān)聯(lián)。一般情況下,在運行期上下文運行的過程中,其作用域鏈只會被 with 語句和 catch 語句影響。
with語句是對象的快捷應用方式,用來避免書寫重復代碼。
對with語句來說,會將指定的對象添加到作用域鏈中,對catch語句來說,會創(chuàng)建一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明。
此時,作用域鏈中函數(shù)的所有局部變量所在的作用域?qū)ο髸煌坪?,訪問代價變高了。
在實際應用中,應少用with,把catch中的錯誤委托給一個函數(shù)處理。

沒有塊級作用域
  if(true){
    var i = 0;
    i++;
  }
  console.log(i); //1

如果在c、c++或java語言中,if語句執(zhí)行完畢后i會被銷毀,而在js中,if語句中的變量聲明是添加到了當前函數(shù)的執(zhí)行環(huán)境中,所以在if語句之后仍然可以正常訪問。

模仿塊級作用域
(function(){
  //這里是塊級作用域
})();

將函數(shù)聲明包含在一對圓括號中,表示它實際上是一個函數(shù)表達式,而緊隨其后的另一對圓括號會立即調(diào)用這個函數(shù)。

小結(jié)

作用域就是變量和函數(shù)的可訪問范圍,通常,局部環(huán)境中的變量和函數(shù)是不能被外部環(huán)境訪問的;

作用域鏈決定了哪些數(shù)據(jù)能夠被當前函數(shù)訪問以及訪問的順序;

函數(shù)創(chuàng)建時,會創(chuàng)建一個Global Object,填入它的作用域鏈;函數(shù)執(zhí)行時,會創(chuàng)建一個運行期上下文的對象,它定義了函數(shù)執(zhí)行時的環(huán)境。函數(shù)執(zhí)行環(huán)境包含一個活動對象,該對象包含了函數(shù)的所有局部變量、命名參數(shù)、參數(shù)集合以及this,它會被推入作用域鏈的最前端;

函數(shù)執(zhí)行過程,每遇到一個變量,都會經(jīng)歷一次標識符解析的過程(逐級向上搜索作用域鏈)以決定從哪里獲取和存儲數(shù)據(jù);

全局變量存在于運行期上下文作用域鏈的最末端,查找最慢,所以我們應該盡可能少使用全局變量,如果使用,就先用局部變量緩存下來;

在運行期上下文運行的過程中,其作用域鏈只會被 with 語句和 catch 語句影響,應少用with,把catch中的錯誤委托給一個函數(shù)處理;

js中沒有塊級作用域,但是我們可以模仿實現(xiàn)它。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86111.html

相關(guān)文章

  • 深入理解JavaScript作用域和作用域鏈

    前言 JavaScript中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運行時代碼中的某些特定部分中變量,函數(shù)和對象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見...

    baiy 評論0 收藏0
  • 深入理解JavaScript作用域和作用域鏈

    前言 JavaScript中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運行時代碼中的某些特定部分中變量,函數(shù)和對象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見...

    ytwman 評論0 收藏0
  • 關(guān)于javascript中的作用域和作用域鏈

    摘要:作用域的類別可以影響到變量的取值,分為詞法作用域靜態(tài)作用域和動態(tài)作用域。而,采用的就是詞法作用域,或者叫靜態(tài)作用域。 關(guān)于javascript中的作用域和作用域鏈 我GitHub上的菜鳥倉庫地址: 點擊跳轉(zhuǎn)查看其他相關(guān)文章 文章在我的博客上的地址: 點擊跳轉(zhuǎn) ? ? ? ? 前面的文章說到, 執(zhí)行上下文的創(chuàng)建階段,主要有三個內(nèi)容: ? ? ? ? 1、創(chuàng)建變量對象;2、初始化作用域...

    lcodecorex 評論0 收藏0
  • 深入javascript——作用域和閉包

    摘要:注意由于閉包會額外的附帶函數(shù)的作用域內(nèi)部匿名函數(shù)攜帶外部函數(shù)的作用域,因此,閉包會比其它函數(shù)多占用些內(nèi)存空間,過度的使用可能會導致內(nèi)存占用的增加。 作用域和作用域鏈是javascript中非常重要的特性,對于他們的理解直接關(guān)系到對于整個javascript體系的理解,而閉包又是對作用域的延伸,也是在實際開發(fā)中經(jīng)常使用的一個特性,實際上,不僅僅是javascript,在很多語言中都...

    oogh 評論0 收藏0
  • JavaScript 作用域和作用域鏈學習

    摘要:作用域與作用域鏈每個函數(shù)都有自己的執(zhí)行環(huán)境。這是初步了解作用域,如想更深入了解作用域,請看下面鏈接作用域原理作用域鏈由一道題圖解的作用域或者看權(quán)威指南和高級程序設(shè)計 本文是我學習JavaScript作用域整理的筆記,如有不對,請多指出。 作用域 一個變量的作用域是程序源代碼中定義這個變量的區(qū)域。 而在ES5中只分為全局作用域和函數(shù)作用域,也就是說for,if,while等語句是不會創(chuàng)建...

    史占廣 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<