国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

深入理解javascript作用域第二篇之詞法作用域和動態作用域

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

前面的話

  大多數時候,我們對作用域產生混亂的主要原因是分不清楚應該按照函數位置的嵌套順序,還是按照函數的調用順序進行變量查找。再加上this機制的干擾,使得變量查找極易出錯。這實際上是由兩種作用域工作模型導致的,作用域分為詞法作用域和動態作用域,分清這兩種作用域模型就能夠對變量查找過程有清晰的認識。本文是深入理解javascript作用域系列第二篇――詞法作用域和動態作用域

詞法作用域

  第一篇介紹過,編譯器的第一個工作階段叫作分詞,就是把由字符組成的字符串分解成詞法單元。這個概念是理解詞法作用域的基礎

  簡單地說,詞法作用域就是定義在詞法階段的作用域,是由寫代碼時將變量和塊作用域寫在哪里來決定的,因此當詞法分析器處理代碼時會保持作用域不變

關系

  無論函數在哪里被調用,也無論它如何被調用,它的詞法作用域都只由函數被聲明時所處的位置決定

function foo(a) {var b = a * 2;function bar(c) {console.log( a, b, c );}bar(b * 3);}foo( 2 ); // 2 4 12

  在這個例子中有三個逐級嵌套的作用域。為了幫助理解,可以將它們想象成幾個逐級包含的氣泡

  作用域氣泡由其對應的作用域塊代碼寫在哪里決定,它們是逐級包含的

  氣泡1包含著整個全局作用域,其中只有一個標識符:foo

  氣泡2包含著foo所創建的作用域,其中有三個標識符:a、bar和b

  氣泡3包含著bar所創建的作用域,其中只有一個標識符:c

查找

  作用域氣泡的結構和互相之間的位置關系給引擎提供了足夠的位置信息,引擎用這些信息來查找標識符的位置

  在代碼片段中,引擎執行console.log(...)聲明,并查找a、b和c三個變量的引用。它首先從最內部的作用域,也就是bar(...)函數的作用域開始查找。引擎無法在這里找到a,因此會去上一級到所嵌套的foo(...)的作用域中繼續查找。在這里找到了a,因此引擎使用了這個引用。對b來講也一樣。而對c來說,引擎在bar(...)中找到了它

  [注意]詞法作用域查找只會查找一級標識符,如果代碼引用了foo.bar.baz,詞法作用域查找只會試圖查找foo標識符,找到這個變量后,對象屬性訪問規則分別接管對bar和baz屬性的訪問

foo = {bar:{baz: 1}};console.log(foo.bar.baz);//1

遮蔽

  作用域查找從運行時所處的最內部作用域開始,逐級向外或者說向上進行,直到遇見第一個匹配的標識符為止

  在多層的嵌套作用域中可以定義同名的標識符,這叫作“遮蔽效應”,內部的標識符“遮蔽”了外部的標識符

var a = 0;function test(){var a = 1;console.log(a);//1}test();

  全局變量會自動為全局對象的屬性,因此可以不直接通過全局對象的詞法名稱,而是間接地通過對全局對象屬性的引用來對其進行訪問

var a = 0;function test(){var a = 1;console.log(window.a);//0}test();

  通過這種技術可以訪問那些被同名變量所遮蔽的全局變量。但非全局的變量如果被遮蔽了,無論如何都無法被訪問到

動態作用域

  javascript使用的是詞法作用域,它的最重要的特征是它的定義過程發生在代碼的書寫階段

  那為什么要介紹動態作用域呢?實際上動態作用域是javascript另一個重要機制this的表親。作用域混亂多數是因為詞法作用域和this機制相混淆,傻傻分不清楚

  動態作用域并不關心函數和作用域是如何聲明以及在任何處聲明的,只關心它們從何處調用。換句話說,作用域鏈是基于調用棧的,而不是代碼中的作用域嵌套

var a = 2;function foo() {console.log( a );}function bar() {var a = 3;foo();}bar();

  【1】如果處于詞法作用域,也就是現在的javascript環境。變量a首先在foo()函數中查找,沒有找到。于是順著作用域鏈到全局作用域中查找,找到并賦值為2。所以控制臺輸出2

  【2】如果處于動態作用域,同樣地,變量a首先在foo()中查找,沒有找到。這里會順著調用棧在調用foo()函數的地方,也就是bar()函數中查找,找到并賦值為3。所以控制臺輸出3

  小結:兩種作用域的區別,簡而言之,詞法作用域是在定義時確定的,而動態作用域是在運行時確定的

以上所述是小編給大家介紹的深入理解javascript作用域第二篇之詞法作用域和動態作用域,希望對大家有所幫助,如果大家想了解更多內容敬請關注武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 开远市| 海南省| 微山县| 白沙| 从江县| 收藏| 安岳县| 安吉县| 康马县| 辽宁省| 旬邑县| 龙游县| 嘉黎县| 嘉定区| 万山特区| 甘孜| 前郭尔| 泸州市| 古蔺县| 嘉定区| 宝鸡市| 望城县| 余江县| 赞皇县| 龙南县| 青河县| 永和县| 石首市| 怀柔区| 曲沃县| 德庆县| 黎城县| 宜黄县| 德清县| 牙克石市| 彰化市| 城固县| 湖南省| 怀安县| 南平市| 名山县|