成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

前端基礎(chǔ)進(jìn)階(三):變量對(duì)象詳解

YJNldm / 1901人閱讀

摘要:創(chuàng)建階段在這個(gè)階段中,執(zhí)行上下文會(huì)分別創(chuàng)建變量對(duì)象,建立作用域鏈,以及確定的指向。檢查當(dāng)前上下文中的參數(shù),建立該對(duì)象下的屬性與屬性值。全局上下文的變量對(duì)象以瀏覽器中為例,全局對(duì)象為。前端基礎(chǔ)進(jìn)階系列目錄

開(kāi)年之后工作熱情一直不是很高,這幾天一直處于消極怠工狀態(tài)。早上不想起床,起床了不想上班。明明放假之前工作熱情還一直很高,一直心心念念的想把小程序項(xiàng)目懟出來(lái),結(jié)果休假回來(lái)之后畫(huà)風(fēng)完全不一樣了。我感覺(jué)自己得了嚴(yán)重了節(jié)后綜合征。還好擼了幾篇文章,勉強(qiáng)表示這一周的時(shí)間沒(méi)有完全浪費(fèi)。這篇文章要給大家介紹的是變量對(duì)象。

在JavaScript中,我們肯定不可避免的需要聲明變量和函數(shù),可是JS解析器是如何找到這些變量的呢?我們還得對(duì)執(zhí)行上下文有一個(gè)進(jìn)一步的了解。

在上一篇文章中,我們已經(jīng)知道,當(dāng)調(diào)用一個(gè)函數(shù)時(shí)(激活),一個(gè)新的執(zhí)行上下文就會(huì)被創(chuàng)建。而一個(gè)執(zhí)行上下文的生命周期可以分為兩個(gè)階段。

創(chuàng)建階段

在這個(gè)階段中,執(zhí)行上下文會(huì)分別創(chuàng)建變量對(duì)象,建立作用域鏈,以及確定this的指向。

代碼執(zhí)行階段

創(chuàng)建完成之后,就會(huì)開(kāi)始執(zhí)行代碼,這個(gè)時(shí)候,會(huì)完成變量賦值,函數(shù)引用,以及執(zhí)行其他代碼。

從這里我們就可以看出詳細(xì)了解執(zhí)行上下文極為重要,因?yàn)槠渲猩婕暗搅俗兞繉?duì)象,作用域鏈,this等很多人沒(méi)有怎么弄明白,但是卻極為重要的概念,它關(guān)系到我們能不能真正理解JavaScript。在后面的文章中我們會(huì)一一詳細(xì)總結(jié),這里我們先重點(diǎn)了解變量對(duì)象。

變量對(duì)象(Variable Object)

變量對(duì)象的創(chuàng)建,依次經(jīng)歷了以下幾個(gè)過(guò)程。

建立arguments對(duì)象。檢查當(dāng)前上下文中的參數(shù),建立該對(duì)象下的屬性與屬性值。

檢查當(dāng)前上下文的函數(shù)聲明,也就是使用function關(guān)鍵字聲明的函數(shù)。在變量對(duì)象中以函數(shù)名建立一個(gè)屬性,屬性值為指向該函數(shù)所在內(nèi)存地址的引用。如果函數(shù)名的屬性已經(jīng)存在,那么該屬性將會(huì)被新的引用所覆蓋。

檢查當(dāng)前上下文中的變量聲明,每找到一個(gè)變量聲明,就在變量對(duì)象中以變量名建立一個(gè)屬性,屬性值為undefined。如果該變量名的屬性已經(jīng)存在,為了防止同名的函數(shù)被修改為undefined,則會(huì)直接跳過(guò),原屬性值不會(huì)被修改。

許多讀者在閱讀到這的時(shí)候會(huì)因?yàn)橄旅娴倪@樣場(chǎng)景對(duì)于“跳過(guò)”一詞產(chǎn)生疑問(wèn)。既然變量聲明的foo遇到函數(shù)聲明的foo會(huì)跳過(guò),可是為什么最后foo的輸出結(jié)果仍然是被覆蓋了?

function foo() { console.log("function foo") }
var foo = 20;

console.log(foo); // 20

其實(shí)只是大家在閱讀的時(shí)候不夠仔細(xì),因?yàn)樯厦娴娜龡l規(guī)則僅僅適用于變量對(duì)象的創(chuàng)建過(guò)程。也就是執(zhí)行上下文的創(chuàng)建過(guò)程。而foo = 20是在執(zhí)行上下文的執(zhí)行過(guò)程中運(yùn)行的,輸出結(jié)果自然會(huì)是20。對(duì)比下例。

console.log(foo); // function foo
function foo() { console.log("function foo") }
var foo = 20;
// 上栗的執(zhí)行順序?yàn)?
// 首先將所有函數(shù)聲明放入變量對(duì)象中
function foo() { console.log("function foo") }

// 其次將所有變量聲明放入變量對(duì)象中,但是因?yàn)閒oo已經(jīng)存在同名函數(shù),因此此時(shí)會(huì)跳過(guò)undefined的賦值
// var foo = undefined;

// 然后開(kāi)始執(zhí)行階段代碼的執(zhí)行
console.log(foo); // function foo
foo = 20;

根據(jù)這個(gè)規(guī)則,理解變量提升就變得十分簡(jiǎn)單了。在很多文章中雖然提到了變量提升,但是具體是怎么回事還真的很多人都說(shuō)不出來(lái),以后在面試中用變量對(duì)象的創(chuàng)建過(guò)程跟面試官解釋變量提升,保證瞬間提升逼格。

在上面的規(guī)則中我們看出,function聲明會(huì)比var聲明優(yōu)先級(jí)更高一點(diǎn)。為了幫助大家更好的理解變量對(duì)象,我們結(jié)合一些簡(jiǎn)單的例子來(lái)進(jìn)行探討。

// demo01
function test() {
    console.log(a);
    console.log(foo());

    var a = 1;
    function foo() {
        return 2;
    }
}

test();

在上例中,我們直接從test()的執(zhí)行上下文開(kāi)始理解。全局作用域中運(yùn)行test()時(shí),test()的執(zhí)行上下文開(kāi)始創(chuàng)建。為了便于理解,我們用如下的形式來(lái)表示

// 創(chuàng)建過(guò)程
testEC = {
    // 變量對(duì)象
    VO: {},
    scopeChain: {}
}

// 因?yàn)楸疚臅簳r(shí)不詳細(xì)解釋作用域鏈,所以把變量對(duì)象專(zhuān)門(mén)提出來(lái)說(shuō)明

// VO 為 Variable Object的縮寫(xiě),即變量對(duì)象
VO = {
    arguments: {...},  //注:在瀏覽器的展示中,函數(shù)的參數(shù)可能并不是放在arguments對(duì)象中,這里為了方便理解,我做了這樣的處理
    foo:   // 表示foo的地址引用
    a: undefined
}

未進(jìn)入執(zhí)行階段之前,變量對(duì)象中的屬性都不能訪(fǎng)問(wèn)!但是進(jìn)入執(zhí)行階段之后,變量對(duì)象轉(zhuǎn)變?yōu)榱嘶顒?dòng)對(duì)象,里面的屬性都能被訪(fǎng)問(wèn)了,然后開(kāi)始進(jìn)行執(zhí)行階段的操作。

這樣,如果再面試的時(shí)候被問(wèn)到變量對(duì)象和活動(dòng)對(duì)象有什么區(qū)別,就又可以自如的應(yīng)答了,他們其實(shí)都是同一個(gè)對(duì)象,只是處于執(zhí)行上下文的不同生命周期。不過(guò)只有處于函數(shù)調(diào)用棧棧頂?shù)膱?zhí)行上下文中的變量對(duì)象,才會(huì)變成活動(dòng)對(duì)象。
// 執(zhí)行階段
VO ->  AO   // Active Object
AO = {
    arguments: {...},
    foo: ,
    a: 1,
    this: Window
}

因此,上面的例子demo1,執(zhí)行順序就變成了這樣

function test() {
    function foo() {
        return 2;
    }
    var a;
    console.log(a);
    console.log(foo());
    a = 1;
}

test();

再來(lái)一個(gè)例子,鞏固一下我們的理解。

// demo2
function test() {
    console.log(foo);
    console.log(bar);

    var foo = "Hello";
    console.log(foo);
    var bar = function () {
        return "world";
    }

    function foo() {
        return "hello";
    }
}

test();
// 創(chuàng)建階段
VO = {
    arguments: {...},
    foo: ,
    bar: undefined
}
// 這里有一個(gè)需要注意的地方,因?yàn)関ar聲明的變量當(dāng)遇到同名的屬性時(shí),會(huì)跳過(guò)而不會(huì)覆蓋
// 執(zhí)行階段
VO -> AO
VO = {
    arguments: {...},
    foo: "Hello",
    bar: ,
    this: Window
}

需要結(jié)合上面的知識(shí),仔細(xì)對(duì)比這個(gè)例子中變量對(duì)象從創(chuàng)建階段到執(zhí)行階段的變化,如果你已經(jīng)理解了,說(shuō)明變量對(duì)象相關(guān)的東西都已經(jīng)難不倒你了。

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

以瀏覽器中為例,全局對(duì)象為window。
全局上下文有一個(gè)特殊的地方,它的變量對(duì)象,就是window對(duì)象。而這個(gè)特殊,在this指向上也同樣適用,this也是指向window。

// 以瀏覽器中為例,全局對(duì)象為window
// 全局上下文
windowEC = {
    VO: Window,
    scopeChain: {},
    this: Window
}

除此之外,全局上下文的生命周期,與程序的生命周期一致,只要程序運(yùn)行不結(jié)束,比如關(guān)掉瀏覽器窗口,全局上下文就會(huì)一直存在。其他所有的上下文環(huán)境,都能直接訪(fǎng)問(wèn)全局上下文的屬性。

前端基礎(chǔ)進(jìn)階系列目錄

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/90522.html

相關(guān)文章

  • 前端基礎(chǔ)進(jìn)階目錄

    摘要:不過(guò)其實(shí)簡(jiǎn)書(shū)文章評(píng)論里有很多大家的問(wèn)題以及解答,對(duì)于進(jìn)一步理解文中知識(shí)幫助很大的,算是有點(diǎn)可惜吧。不過(guò)也希望能夠?qū)φ趯W(xué)習(xí)前端的你有一些小幫助。如果在閱讀中發(fā)現(xiàn)了一些錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論里告訴我,我會(huì)及時(shí)更改。 前端基礎(chǔ)進(jìn)階(一):內(nèi)存空間詳細(xì)圖解 前端基礎(chǔ)進(jìn)階(二):執(zhí)行上下文詳細(xì)圖解 前端基礎(chǔ)進(jìn)階(三):變量對(duì)象詳解 前端基礎(chǔ)進(jìn)階(四):詳細(xì)圖解作用域鏈與閉包 前端基礎(chǔ)進(jìn)階(五):全方位...

    mo0n1andin 評(píng)論0 收藏0
  • 【連載】前端個(gè)人文章整理-從基礎(chǔ)到入門(mén)

    摘要:個(gè)人前端文章整理從最開(kāi)始萌生寫(xiě)文章的想法,到著手開(kāi)始寫(xiě),再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫(xiě)好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開(kāi)始萌生寫(xiě)文章的想法,到著手...

    madthumb 評(píng)論0 收藏0
  • 進(jìn)階1-3期】JavaScript深入之內(nèi)存空間詳細(xì)圖解

    摘要:進(jìn)階期理解中的執(zhí)行上下文和執(zhí)行棧進(jìn)階期深入之執(zhí)行上下文棧和變量對(duì)象但是今天補(bǔ)充一個(gè)知識(shí)點(diǎn)某些情況下,調(diào)用堆棧中函數(shù)調(diào)用的數(shù)量超出了調(diào)用堆棧的實(shí)際大小,瀏覽器會(huì)拋出一個(gè)錯(cuò)誤終止運(yùn)行。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第3天。 本計(jì)劃一共28期,每期重點(diǎn)攻...

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

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

0條評(píng)論

閱讀需要支付1元查看
<