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

資訊專欄INFORMATION COLUMN

javascript作用域鏈詳解

NeverSayNever / 2580人閱讀

摘要:文章部分實例和內(nèi)容來自鳥哥的作用域原理首先應該注意幾個點函數(shù)也是對象因為是在全局作用域當中當執(zhí)行到時即會產(chǎn)生在當中,函數(shù)的運行是在它被定義的作用域當中,而非執(zhí)行的作用域當中。

文章部分實例和內(nèi)容來自鳥哥的blogJavascript作用域原理

首先應該注意幾個點:

函數(shù)也是對象

variable object(VO)

A variable object is a container of data associated with the execution context. It’s a special object that stores variables and function declarations defined in the context.

    var foo=10;
    function func(){};
    
    //因為是在全局作用域當中,so...
    Global VO={
        foo:10,
        func:
    }

Activation Object(AO)

When a function is activated (called) by the caller, a special object, called an activation object is created.

It’s filled with formal parameters and the special arguments object (which is a map of formal parameters but with index-properties). The activation object then is used as a variable object of the function context.

A function’s variable object is the same simple variable object, but besides variables and function declarations, it also stores formal parameters and arguments object and called the activation object.

    function foo(x,y){
        var z=30;
        function bar(){};
    }
    foo(10,20);
    //當執(zhí)行到foo(10,20)時即會產(chǎn)生AO
    Activation Object={
        z:30,
        x:10,
        y:20,
        bar:,
        arguments:{0:10,1:20,length:2}
    }

Scope Chain(Scope Chain=Activation Object + [[scope]])

A scope chain is a list of objects that are searched for identifiers appear in the code of the context.

在JavaScript當中,函數(shù)的運行是在它被定義的作用域當中,而非執(zhí)行的作用域當中。

先看一段代碼:

    var name="laurence?";
    
    function show(){
        console.log(name);
        var name="laurence?";
        console.log(name);
    }

最后輸出: undefined  laurence?



Object={
    name1:undefined,//第一個輸出為undefined,表達式聲明的局部變量覆蓋全局變量,函數(shù)執(zhí)行到這一語句的時候才進行賦值操作name="laurence?",之前name=undefined
    name2:"laurence?",//第二個輸出為"laurence?"
}
window={
    name:"laurence?",
    show:function()
}
    

注意點:

函數(shù)也是對象

變量提升

函數(shù)在定義過程中,會將定義時刻的scope chain鏈接到這個函數(shù)對象的[[scope]]屬性上,這個屬性包含了函數(shù)被創(chuàng)建的作用域中 對象 的集合,同時它的作用域會被創(chuàng)建此函數(shù)的作用域中可訪問的數(shù)據(jù)對象填充。(對象的集合、對象鏈)

函數(shù)的執(zhí)行過程中,會創(chuàng)建一個 活動對象 (activation object),該對象包含了所有的局部變量、命名參數(shù)、參數(shù)集合this,然后將這個活動對象作為此時作用域鏈的最前端,每個活動對象都有自己的作用域鏈,用于標識符的解析,當活動對象被創(chuàng)建時,而它的作用域初始化為當前運行函數(shù)的[[scope]]所包含的對象。

var func=function(lps,rps){
    var name="XL";
    ....
}
func();

var func=function(){ } 相當于匿名函數(shù)的執(zhí)行

(在執(zhí)行函數(shù)創(chuàng)建活動對象(Obj)的過程中,會創(chuàng)建一個arguments屬性,然后會給這個活動對象添加2個屬性名,Obj.lps,Obj.rps對于每一個在這個函數(shù)中申明的局部變量和函數(shù)定義,都作為該活動對象的同名屬性,然后將調(diào)用參數(shù)賦值給形參,對于缺少的調(diào)用參數(shù),賦值為undefined)

//這里func()執(zhí)行時
Obj(AO)={
    lps:undefined,
    rps:undefined,
    arguments:{}
    name:"XL"
}
//創(chuàng)建func()時為全局對象:
window(Global VO)={
    func:function()
}

實際的例子:

function factory(){
    var name="laruence";
    var intro=function(){
        console.log("I"m "+name);
    }
    return intro;
}
function app(para){
    var name=para;
    var func=factory();
    func();
}

app("eve");

當調(diào)用app的時候,scope chain是由{window活動對象(全局)}+{app活動對象}組成

此時的[[scope chain]]為( 可訪問的數(shù)據(jù)對象訪問 ):

[[scope chain]]=[
Active Object={
    this:window,
    arguments:{0:"eve",length:1}
    name:"eve"
    func:
    para:"eve",
},
Global VO={
    this:window,
    app:,
    window:,
    document:
}
]

當調(diào)用進入factory函數(shù)體內(nèi)時(注意這里,函數(shù)的scope chain是在它被定義的時候決定的,而非執(zhí)行的時候決定的),此時的factory的scope chain為:

[[scope chain]]={
Active Object={
    this:window,
    arguments:{},
    name:"laruence",
    intro:,
},
Global Object(Variable Object)={
   this:window,
   factory:,
   app:,
   window:,
   document:
}
}

在定義intro函數(shù)的時候,intro函數(shù)[[scope]]為:

[[scope chain]]={
Object={
    name:"laruence",
    intro:,
    this:,     //注意這里的this指向
    arguments:{}
},
Gloabal Object={
    this:window,
    factory:,
    document:,
    window:
}
}

factory函數(shù)返回后,在app體內(nèi)調(diào)用intro時,發(fā)生了標識符的解析,而此時的scope chain是:

[[scope chain]]={
  intro AO={
        
  } ,
  Factory AO={
        name:"laruence",
        intro:,
  },
  Global VO={
        this:window,
        factory:,
        document:,
        window:
  }
}

在intro執(zhí)行過程中scope chain不包含app活動對象,因此name標識符解析的結果應該是factory活動對象中的name屬性,也就是"laruence"

預編譯

JS在執(zhí)行每段代碼前都會首先處理var關鍵字( 函數(shù)定義式 )和function定義式( 函數(shù)聲明式 )

變量提升(hoisting)

1.javascript-the-core(強烈推薦)
2.理解javascript作用域和作用域鏈

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

轉載請注明本文地址:http://systransis.cn/yun/85909.html

相關文章

  • 詳解js變量、作用域及內(nèi)存

    摘要:不是引用類型,無法輸出簡而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類型值。變量的查詢在變量的查詢中,訪問局部變量要比全局變量來得快,因此不需要向上搜索作用域鏈。 贊助我以寫出更好的文章,give me a cup of coffee? 2017最新最全前端面試題 基本類型值有:undefined,NUll,Boolean,Number和String,這些類型分別在內(nèi)存中占有固定的大小空...

    waltr 評論0 收藏0
  • 閉包詳解

    摘要:函數(shù)中的閉包閉包是指有權訪問另一個函數(shù)作用域中的變量的函數(shù)。理解閉包預與變量此時返回注意觀察下面的輸出內(nèi)容,理解函數(shù)的調(diào)用時刻和把的賦值給變量時刻這個函數(shù)會返回長度為的函數(shù)數(shù)組。 Javascript函數(shù)中的閉包 閉包是指有權訪問另一個函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式就是,在一個函數(shù)的內(nèi)部創(chuàng)建另一個函數(shù)。 有關創(chuàng)建作用域鏈以及作用域鏈有什么作用的細節(jié)對于徹底理解閉包至關重...

    lunaticf 評論0 收藏0
  • 閉包全面詳解

    摘要:環(huán)境由閉包創(chuàng)建時在作用域中的任何局部變量組成。嚴格來說,閉包需要滿足三個條件訪問所在作用域函數(shù)嵌套在所在作用域外被調(diào)用閉包的形成原理先了解的垃圾回收機制會找出不再使用的變量,不再使用意味著這個變量生命周期的結束。 什么是閉包 最原始定義 閉包(closure),是指函數(shù)變量可以保存在函數(shù)作用域內(nèi),因此看起來是函數(shù)將變量包裹了起來。 //根據(jù)定義,包含變量的函數(shù)就是閉包 function...

    qylost 評論0 收藏0
  • 詳解js中的閉包

    摘要:定義函數(shù)的時候,為什么的值重新從開始了因為又一次運行了函數(shù),生成一個新的的活動對象,所以的作用域鏈引用的是一個新的值。 前言 在js中,閉包是一個很重要又相當不容易完全理解的要點,網(wǎng)上關于講解閉包的文章非常多,但是并不是非常容易讀懂,在這里以《javascript高級程序設計》里面的理論為基礎。用拆分的方式,深入講解一下對于閉包的理解,如果有不對請指正。 寫在閉包之前 閉包的內(nèi)部細節(jié),...

    chaosx110 評論0 收藏0

發(fā)表評論

0條評論

NeverSayNever

|高級講師

TA的文章

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