九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
前端基礎(chǔ)進(jìn)階(三):變量對(duì)象詳解


作者:波同學(xué) 

www.jianshu.com/p/330b1505e41d

如有好文章投稿,請(qǐng)點(diǎn)擊 → 這里了解詳情



開(kāi)年之后工作熱情一直不是很高,這幾天一直處于消極怠工狀態(tài)。早上不想起床,起床了不想上班。明明放假之前工作熱情還一直很高,一直心心念念的想把小程序項(xiàng)目懟出來(lái),結(jié)果休假回來(lái)之后畫風(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í)行其他代碼。


執(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ò)程。


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

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

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


我知道有的人不喜歡看文字


根據(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: {},

    this: {}

}

 

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

 

// VO 為 Variable Object的縮寫,即變量對(duì)象

VO = {

    arguments: {...},  //注:在瀏覽器的展示中,函數(shù)的參數(shù)可能并不是放在arguments對(duì)象中,這里為了方便理解,我做了這樣的處理

    foo: foo reference>  // 表示foo的地址引用

    a: undefined

}


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


這樣,如果再面試的時(shí)候被問(wèn)到變量對(duì)象和活動(dòng)對(duì)象有什么區(qū)別,就又可以自如的應(yīng)答了,他們其實(shí)都是同一個(gè)對(duì)象,只是處于執(zhí)行上下文的不同生命周期。


// 執(zhí)行階段

VO ->  AO   // Active Object

AO = {

    arguments: {...},

    foo: foo reference>,

    a: 1

}


因此,上面的例子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: foo reference>,

    bar: undefined

}

// 這里有一個(gè)需要注意的地方,因?yàn)関ar聲明的變量當(dāng)遇到同名的屬性時(shí),會(huì)跳過(guò)而不會(huì)覆蓋


// 執(zhí)行階段

VO -> AO

VO = {

    arguments: {...},

    foo: 'Hello',

    bar: bar reference>

}


需要結(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)境,都能直接訪問(wèn)全局上下文的屬性。



看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人

關(guān)注「前端大全」,提升前端技能

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JavaScript作用域鏈其二:函數(shù)的生命周期
深入理解JavaScript系列(14):作用域鏈(Scope Chain)
深入理解JavaScript系列(12):變量對(duì)象(Variable Object)
手把手教會(huì)你JavaScript引擎如何執(zhí)行JavaScript代碼
【Python之路】特別篇
變量對(duì)象(Variable object)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服