亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

代碼真的被提升了嗎?

weknow619 / 3231人閱讀

摘要:為啥因?yàn)樽兞刻嵘?,變量的聲明被提升到?dāng)前作用域的頂部了。也就是可以想象成這樣此外,還有函數(shù)提升,和變量提升類似和被提升了,所以不會(huì)報(bào)錯(cuò)。開始處理函數(shù)聲明,再次提醒,函數(shù)表達(dá)式不會(huì)被處理。

變量提升 & 函數(shù)提升
function f() {
    console.log(a); // ?
    var a = 1;
}
f();

簡(jiǎn)單簡(jiǎn)單,打印結(jié)果是 undefined。為啥?因?yàn)樽兞刻嵘?,變?a 的聲明被提升到當(dāng)前作用域的頂部了。也就是可以想象成這樣:

function f() {
    var a;
    console.log(a);
    a = 1;
}

此外,還有函數(shù)提升,和變量提升類似:

f1();

f2();

function f1() { console.log(1) }

function f2() { console.log(2) }

f1 和 f2 被提升了,所以不會(huì)報(bào)錯(cuò)。很多文章中都會(huì)經(jīng)常提到提升這個(gè)概念。
但是,這是真的嗎?JS 解釋器在執(zhí)行代碼時(shí)還順帶幫你變動(dòng)一下代碼的順序?想想也覺得不太可能嘛~那么到底是咋回事捏?

可執(zhí)行代碼

JavaScript 的可執(zhí)行代碼(executable code)有三種,分別為 全局代碼、函數(shù)代碼以及 eval 代碼。鑒于 eval 不被推薦使用,咱就不理它。

執(zhí)行上下文

當(dāng)執(zhí)行全局代碼時(shí),會(huì)創(chuàng)建一個(gè)全局執(zhí)行上下文。當(dāng)執(zhí)行一個(gè)函數(shù)的時(shí)候,會(huì)創(chuàng)建一個(gè)函數(shù)執(zhí)行上下文。全局執(zhí)行上下文只會(huì)有一個(gè),而函數(shù)執(zhí)行上下文可以有很多很多個(gè)。JS 引擎會(huì)創(chuàng)建 執(zhí)行上下文棧(execution context stack, ECS)去管理這些執(zhí)行上下文。我們以函數(shù)執(zhí)行上下文為例。

變量對(duì)象

對(duì)于一個(gè)執(zhí)行上下文而言,可以抽象化為這樣一個(gè)對(duì)象:

contextObject = {
    VariableObject,
    ScopeChain,
    thisValue
}

其中變量對(duì)象(Variable Object,VO)是包含與當(dāng)前執(zhí)行上下文相關(guān)的數(shù)據(jù)作用域,它存儲(chǔ)著當(dāng)前上下文中定義的變量聲明、函數(shù)聲明(注意:不包含函數(shù)表達(dá)式),另外函數(shù)執(zhí)行上下文中還會(huì)有參數(shù)。

變量對(duì)象是一個(gè)抽象概念,在不同的執(zhí)行上下文中會(huì)以不同的對(duì)象呈現(xiàn)。比如在全局上下文中,變量對(duì)象就是全局對(duì)象本身(這也是為什么我們能夠通過全局對(duì)象的屬性名稱引用全局變量)。而對(duì)于函數(shù)執(zhí)行上下文,是用活動(dòng)對(duì)象(Activation Object,AO)來表示變量對(duì)象的,我們?cè)L問的便是活動(dòng)對(duì)象上的屬性。

執(zhí)行過程

執(zhí)行上下文中的代碼會(huì)被分出兩個(gè)階段進(jìn)行處理,分別為:

進(jìn)入執(zhí)行上下文,即分析創(chuàng)建階段

執(zhí)行代碼,即執(zhí)行階段

分析創(chuàng)建階段

此時(shí)進(jìn)入執(zhí)行上下文,但在開始執(zhí)行代碼之前。此時(shí)的變量對(duì)象:

如果是函數(shù)上下文,那么會(huì)通過函數(shù)的 arguments 屬性初始化,并處理形參。此時(shí)變量對(duì)象中會(huì)包含一個(gè) arguments 對(duì)象,以及所有的形參,并且會(huì)檢查是否有與之對(duì)應(yīng)的實(shí)參,有則值初始化為實(shí)參的值,沒有的話就設(shè)為 undefined。

處理函數(shù)聲明。開始處理函數(shù)聲明,再次提醒,函數(shù)表達(dá)式不會(huì)被處理。此時(shí)會(huì)檢查變量對(duì)象中是否已經(jīng)有同名屬性,如果有,則替換它,如果沒有則創(chuàng)建屬性,值初始化為對(duì)應(yīng)的函數(shù)對(duì)象。

處理變量聲明。與處理函數(shù)聲明不同的是,如果變量對(duì)象中存在有同名屬性,此時(shí)會(huì)跳過該變量不做任何事,即不會(huì)產(chǎn)生覆蓋,如果沒有則創(chuàng)建屬性并初始化為 undefined。

了解了第一個(gè)階段,那么來看個(gè)例子:

function f(a, b) {
    var c = 3;
    function d() {};
    var e = function() {};
    (function f() {});
}

f(1, 2);

當(dāng)執(zhí)行 f 函數(shù)時(shí),進(jìn)入執(zhí)行上下文,我們可以描述出此時(shí)的 AO:

AO = {
    arguments: {
        0: 1,
        1: 2,
        length: 2
    },
    a: 1,
    b: 2,
    c: undefined,
    d: reference to function() {},
    e: undefined,
}
// 注意:(function f() {}) 為函數(shù)表達(dá)式,不會(huì)被處理
執(zhí)行階段

執(zhí)行階段就相對(duì)簡(jiǎn)單,代碼順序執(zhí)行,并且會(huì)根據(jù)代碼去修改變量對(duì)象中的值,所以當(dāng)函數(shù)執(zhí)行完后的 AO 會(huì)是:

AO = {
    arguments: {
        0: 1,
        1: 2,
        length: 2
    },
    a: 1,
    b: 2,
    c: 3,
    d: reference to function() {},
    e: reference to function() {},
}
總結(jié)

綜上所述:

全局上下文的變量對(duì)象即是全局對(duì)象;

函數(shù)上下文的變量對(duì)象會(huì)以 arguments 對(duì)象初始化;

在第一個(gè)階段會(huì)依次給變量對(duì)象添加形參(函數(shù)上下文)、函數(shù)聲明、變量聲明;

在第二個(gè)階段,會(huì)修改變量對(duì)象中的屬性值。

思考題
console.log(f); // ?

function f() {}
var f = 1;

打印結(jié)果會(huì)是一個(gè)函數(shù)對(duì)象。因?yàn)榈谝粋€(gè)階段中先處理函數(shù)聲明后處理變量聲明,當(dāng)處理變量聲明時(shí)變量對(duì)象中已經(jīng)存在同名屬性 f,不會(huì)做任何事直接跳過,所以 f 的值會(huì)是一個(gè)函數(shù)。

你也可以多找?guī)椎李}嘗試分析以加深理解。當(dāng)然,日常工作中還是直接想成提升來得方便些,只是希望通過本文能讓你了解到一些背后的事情。最后,如果文中有任何錯(cuò)誤或不足之處,還請(qǐng)指出~

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/104225.html

相關(guān)文章

  • 8道經(jīng)典JavaScript面試題解析,你真的掌握J(rèn)avaScript了嗎

    摘要:瀏覽器的主要組成包括有調(diào)用堆棧,事件循環(huán),任務(wù)隊(duì)列和。好了,現(xiàn)在有了前面這些知識(shí),我們可以看一下這道題的講解過程實(shí)現(xiàn)步驟調(diào)用會(huì)將函數(shù)放入調(diào)用堆棧。由于調(diào)用堆棧是空的,事件循環(huán)將選擇回調(diào)并將其推入調(diào)用堆棧進(jìn)行處理。進(jìn)程再次重復(fù),堆棧不會(huì)溢出。 JavaScript是前端開發(fā)中非常重要的一門語言,瀏覽器是他主要運(yùn)行的地方。JavaScript是一個(gè)非常有意思的語言,但是他有很多一些概念,大...

    taowen 評(píng)論0 收藏0
  • 春陽:SaaS已死,下一個(gè)

    摘要:中國(guó)的是一個(gè)陰謀讓我們首先回到的初衷。春陽曾經(jīng)分享過的藏寶圖報(bào)告里有過一個(gè)關(guān)于家廠商毛利水平的統(tǒng)計(jì),如下圖所示,其中位數(shù)是。每一年,都會(huì)有人問我,春陽,你覺得SaaS行業(yè)到時(shí)候了嗎?每一年,都會(huì)有媒體發(fā)文,SaaS已來,未來可期....是的,每一年...行業(yè)的媒體人喜歡給SaaS灌雞湯是沒有毛病的,本身這就是個(gè)留不住人才、熬不出日子的行業(yè),如果我們?cè)倏此ニ?,媒體本身也是活不下去了…對(duì)這個(gè)問題...

    rainyang 評(píng)論0 收藏0
  • PHP socket初探 --- 硬著頭皮繼續(xù)libevent(二)

    摘要:類就是產(chǎn)生各種不同類型事件的產(chǎn)出器,比如定時(shí)器事件讀寫事件等等,為了提升民族榮譽(yù)感,我們將這些各種事件比作各種戰(zhàn)斗機(jī)比如殲殲和殲。類就相對(duì)容易介入了,這玩意顯然就是一個(gè)航空母艦了,為了提升民族榮譽(yù)感,我們就把類當(dāng)作是遼寧艦。 [原文地址:https://blog.ti-node.com/blog...] 實(shí)際上php.net上是有event擴(kuò)展的使用說明手冊(cè),但是呢,對(duì)于初學(xué)者來說卻并...

    jokester 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<