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

資訊專欄INFORMATION COLUMN

javascript作用域,作用域鏈,[[scope]]屬性

pkhope / 1560人閱讀

摘要:正式由于作用域鏈的這種關(guān)系,我們就不難理解,為什么和不能通過作用域鏈向上搜索,因為對和的搜索在當(dāng)前執(zhí)行函數(shù)的活動對象就停止了。

對于Javascript程序員來說,閉包總會讓你覺得既熟悉又陌生,然而它對于開發(fā)人員來說卻非常重要,javascript里的許多設(shè)計模式中都用到了閉包,此處以函數(shù)作用域為例。

//示例代碼
    var a=1;
    function foo(){
        var b=2;
        console.log(a);
        function bar(){
            var c=123;
            console.log(b);
        }
        bar();
    }
    foo();

任何函數(shù)定義的時候,都會創(chuàng)建一個[[scope]]屬性,這個對象對應(yīng)的是一個對象的列表,列表中的對象僅能javascript內(nèi)部訪問,沒法通過語法訪問,用代碼可以表示為:
1.函數(shù)定義時
在全局環(huán)境下定義了一個foo函數(shù),此時foo函數(shù)的[[scope]]屬性中只包含一個全局對象GO(global object)

    //偽代碼
    //js代碼默認(rèn)進入全局執(zhí)行環(huán)境,所以foo在初始時就被定義
    foo.[[scope]]={
        GO:{
        this:window,
        window:{...},
        document:{...},
        a:undefined   //此處是預(yù)編譯,所以a并沒有賦值
        ....
        }
    }
   //當(dāng)進入foo執(zhí)行環(huán)境時,bar函數(shù)才被定義
   bar.[[scope]]={
        AO(foo):{
            this:window,
            arguments:[],
            b:undefined
        },
        GO:{
            this:window,
            window:{...},
            document:{...},
            a:1
        }
    }

2.函數(shù)被調(diào)用時
執(zhí)行環(huán)境
在函數(shù)執(zhí)行時,會創(chuàng)建一個叫做執(zhí)行環(huán)境/執(zhí)行上下文(execution context)的內(nèi)部對象
它定義了一個函數(shù)執(zhí)行時的環(huán)境
函數(shù)每次執(zhí)行時的執(zhí)行環(huán)境獨一無二
多次調(diào)用函數(shù)就多次創(chuàng)建執(zhí)行環(huán)境
并且函數(shù)執(zhí)行完畢后,執(zhí)行環(huán)境就會被銷毀
執(zhí)行環(huán)境有自己的作用域鏈,用于解析標(biāo)識符

所以當(dāng)foo函數(shù)被調(diào)用的時候,會創(chuàng)建foo執(zhí)行環(huán)境,每個執(zhí)行環(huán)境對應(yīng)一個變量對象。首先會創(chuàng)一個它自己的活動對象【Activation Object】(這個對象中包含了this、參數(shù)(arguments)、局部變量(包括命名的參數(shù))的定義,當(dāng)然全局對象是沒有arguments的)和一個變量對象的作用域鏈[[scope chain]],然后,把這個執(zhí)行環(huán)境的[[scope]]按順序復(fù)制到[[scope chain]]里,最后把這個活動對象推入到[[scope chain]]的頂部。這樣[[scope chain]]就是一個有序的棧,這樣保了對執(zhí)行環(huán)境有權(quán)訪問的所有變量和對象的有序訪問。

    //foo函數(shù)被調(diào)用時
    foo.EC={         //foo的執(zhí)行環(huán)境
      AO:{           //foo的活動對象
        this:window,
        arguments:[],
        b:undefined
        },
      [[scope chain]]:{
            AO:AO,   //推入作用域鏈頂部的活動對象
            GO:{...} //通過復(fù)制foo.[[scope]]得到的全局對象
        }
      ...
    }
    //函數(shù)的作用域鏈
    foo.EC.[[scope chain]]={
        AO:{
            this:window,
            arguments:[],
            b:undefined
        },
        GO:{
            this:window,
            window:{...},
            document:{...},
            a:1
        }
    }
   //當(dāng)bar函數(shù)被調(diào)用時
    bar.EC={
        AO:{
            this:window,
            arguments:[],
            c:undefined
        },
        [[scope chain]]:{
            AO:AO     //推入作用域鏈頂部的活動對象
            AO:{...}  //foo活動對象
            GO:{...}  //全局活動對象
        }
    }
    

3.函數(shù)代碼執(zhí)行階段
var b=2 實際上就是對作用域鏈AO對象中的b進行賦值,當(dāng)執(zhí)行console.log(a)時候,遇到標(biāo)識符a,就會根據(jù)標(biāo)識符的名稱在執(zhí)行環(huán)境(Execution Context)的作用域鏈中進行搜索。從作用域鏈的第一個對象(該函數(shù)的Activation Object對象)開始,如果沒有找到,就搜索作用域鏈中的下一個對象,如此往復(fù),直到找到了標(biāo)識符的定義。如果在搜索完作用域中的最后一個對象,也就是全局對象(Global Object)以后也沒有找到,則會拋出一個錯誤,提示undefined。

正式由于作用域鏈的這種關(guān)系,我們就不難理解,為什么this和arguments不能通過作用域鏈向上搜索,因為對this和arguments的搜索在當(dāng)前執(zhí)行函數(shù)的活動對象就停止了。

以上是個人對于js作用域的理解, 如有錯誤歡迎討論,本文未涉及with等改變作用域的行為
參考文章
http://www.cnblogs.com/pigtai...
http://blog.csdn.net/liujie19...
http://www.cnblogs.com/vadar/...
http://blog.csdn.net/q1056843...

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

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

相關(guān)文章

  • JavaScript深入之作用

    摘要:下面,讓我們以一個函數(shù)的創(chuàng)建和激活兩個時期來講解作用域鏈?zhǔn)侨绾蝿?chuàng)建和變化的。這時候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 JavaScript深入系列第五篇,講述作用鏈的創(chuàng)建過程,最后結(jié)合著變量對象,執(zhí)行上下文棧,讓我們一起捋一捋函數(shù)創(chuàng)建和執(zhí)行的過程中到底發(fā)生了什么? 前言 在《JavaScript深入之執(zhí)行上下文?!分兄v到,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代...

    waltr 評論0 收藏0
  • 深入學(xué)習(xí)js之——作用

    摘要:開篇作用域是每種計算機語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)作用域和作用域鏈就是個繞不開的話題。這樣由多個執(zhí)行上下文的變量對象構(gòu)成的鏈表就叫做作用域鏈。這時候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 開篇 作用域是每種計算機語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)JavaScript,作用域和作用域鏈就是個繞不開的話題。 在《深入學(xué)習(xí)js之—-執(zhí)行上下文棧》中我們提到...

    lemanli 評論0 收藏0
  • JavaScript 作用學(xué)習(xí)筆記

    摘要:每一個運行期上下文都和一個作用域鏈關(guān)聯(lián)。這個對象將被推入作用域鏈的頭部,這意味著函數(shù)的所有局部變量現(xiàn)在處于第二個作用域鏈對象中,因此訪問代價更高了。在代碼塊內(nèi)部,函數(shù)的所有局部變量將會被放在第二個作用域鏈對象中。 參考: Javascript作用域原理 理解 JavaScript 作用域和作用域鏈 JavaScript 作用域 作用域就是變量與函數(shù)的可訪問范圍,即作用域控制著變量與函數(shù)...

    趙連江 評論0 收藏0
  • JavaScript-作用-執(zhí)行上下文-變量對象-作用

    摘要:變量對象作用域鏈因為變量對象在執(zhí)行上下文進入執(zhí)行階段時,就變成了活動對象,因此圖中使用了來表示。 作用域 作用域就是變量與函數(shù)的可訪問范圍,即作用域控制著變量與函數(shù)的可見性和生命周期。在 JavaScript 中,變量的作用域有全局作用域和局部作用域兩種。JavaScript 采用詞法作用域(lexical scoping),也就是靜態(tài)作用域。 靜態(tài)作用域 函數(shù)的作用域在函數(shù)定義的時候...

    MonoLog 評論0 收藏0

發(fā)表評論

0條評論

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