最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
當前位置: 首頁 - 科技 - 知識百科 - 正文

前端基礎進階(三):變量對象詳解,教你如何高逼格地解釋變量提升

來源:懂視網 責編:小采 時間:2020-11-27 20:25:14
文檔

前端基礎進階(三):變量對象詳解,教你如何高逼格地解釋變量提升

前端基礎進階(三):變量對象詳解,教你如何高逼格地解釋變量提升:開年之后工作熱情一直不是很高,這幾天一直處于消極怠工狀態。早上不想起床,起床了不想上班。明明放假之前工作熱情還一直很高,一直心心念念的想把小程序項目懟出來,結果休假回來之后畫風完全不一樣了。我感覺自己得了嚴重了節后綜合征。還好擼了幾篇文章,
推薦度:
導讀前端基礎進階(三):變量對象詳解,教你如何高逼格地解釋變量提升:開年之后工作熱情一直不是很高,這幾天一直處于消極怠工狀態。早上不想起床,起床了不想上班。明明放假之前工作熱情還一直很高,一直心心念念的想把小程序項目懟出來,結果休假回來之后畫風完全不一樣了。我感覺自己得了嚴重了節后綜合征。還好擼了幾篇文章,
1.png

開年之后工作熱情一直不是很高,這幾天一直處于消極怠工狀態。早上不想起床,起床了不想上班。明明放假之前工作熱情還一直很高,一直心心念念的想把小程序項目懟出來,結果休假回來之后畫風完全不一樣了。我感覺自己得了嚴重了節后綜合征。還好擼了幾篇文章,勉強表示這一周的時間沒有完全浪費。這篇文章要給大家介紹的是變量對象。

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

在上一篇文章中,我們已經知道,當調用一個函數時(激活),一個新的執行上下文就會被創建。而一個執行上下文的生命周期可以分為兩個階段。

1.創建階段
在這個階段中,執行上下文會分別創建變量對象,建立作用域鏈,以及確定this的指向

2.代碼執行階段
創建完成之后,就會開始執行代碼,這個時候,會完成變量賦值,函數引用,以及執行其他代碼。

2.png

從這里我們就可以看出詳細了解執行上下文極為重要,因為其中涉及到了變量對象,作用域鏈,this等很多人沒有怎么弄明白,但是卻極為重要的概念,因此它關系到我們能不能真正理解JavaScript。在后面的文章中我們會一一詳細總結,這里我們先重點了解變量對象。

變量對象(Variable Object)

變量對象的創建,依次經歷了以下幾個過程。

1.建立arguments對象。檢查當前上下文中的參數,建立該對象下的屬性與屬性值。

2.檢查當前上下文的函數聲明,也就是使用function關鍵字聲明的函數。在變量對象中以函數名建立一個屬性,屬性值為指向該函數所在內存地址的引用。如果函數名的屬性已經存在,那么該屬性將會被新的引用所覆蓋。

3.檢查當前上下文中的變量聲明,每找到一個變量聲明,就在變量對象中以變量名建立一個屬性,屬性值為undefined。如果該變量名的屬性已經存在,為了防止同名的函數被修改為undefined,則會直接跳過,原屬性值不會被修改。

3.png

根據這個規則,理解變量提升就變得十分簡單了。在很多文章中雖然提到了變量提升,但是具體是怎么回事還真的很多人都說不出來,以后在面試中用變量對象的創建過程跟面試官解釋變量提升,保證瞬間提升逼格。

在上面的規則中我們看出,function聲明會比var聲明優先級更高一點。為了幫助大家更好的理解變量對象,我們結合一些簡單的例子來進行探討。

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

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

test();

在上例中,我們直接從test()的執行上下文開始理解。全局作用域中運行test()時,test()的執行上下文開始創建。為了便于理解,我們用如下的形式來表示

創建過程
testEC = {
 // 變量對象
 VO: {},
 scopeChain: {},
 this: {}
}

// 因為本文暫時不詳細解釋作用域鏈和this,所以把變量對象專門提出來說明

// VO 為 Variable Object的縮寫,即變量對象
VO = {
 arguments: {...},
 foo: <foo reference> // 表示foo的地址引用
 a: undefined
}

未進入執行階段之前,變量對象中的屬性都不能訪問!但是進入執行階段之后,變量對象轉變為了活動對象,里面的屬性都能被訪問了,然后開始進行執行階段的操作。

這樣,如果再面試的時候被問到變量對象和活動對象有什么區別,就又可以自如的應答了,他們其實都是同一個對象,只是處于執行上下文的不同生命周期。

// 執行階段
VO -> AO // Active Object
AO = {
 arguments: {...},
 foo: <foo reference>,
 a: 1
}

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

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

test();

再來一個例子,鞏固一下我們的理解。

// 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();
// 創建階段
VO = {
 arguments: {...},
 foo: <foo reference>,
 bar: undefined
}
// 這里有一個需要注意的地方,因為var聲明的變量當遇到同名的屬性時,會跳過而不會覆蓋
// 執行階段
VO -> AO
VO = {
 arguments: {...},
 foo: 'Hello',
 bar: <bar reference>
}

需要結合上面的知識,仔細對比這個例子中變量對象從創建階段到執行階段的變化,如果你已經理解了,說明變量對象相關的東西都已經難不倒你了。

全局上下文的變量對象

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

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

除此之外,全局上下文的生命周期,與程序的生命周期一致,只要程序運行不結束,比如關掉瀏覽器窗口,全局上下文就會一直存在。其他所有的上下文環境,都能直接訪問全局上下文的屬性。

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

前端基礎進階(三):變量對象詳解,教你如何高逼格地解釋變量提升

前端基礎進階(三):變量對象詳解,教你如何高逼格地解釋變量提升:開年之后工作熱情一直不是很高,這幾天一直處于消極怠工狀態。早上不想起床,起床了不想上班。明明放假之前工作熱情還一直很高,一直心心念念的想把小程序項目懟出來,結果休假回來之后畫風完全不一樣了。我感覺自己得了嚴重了節后綜合征。還好擼了幾篇文章,
推薦度:
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
国产精品久久久久精品…-国产精品可乐视频最新-亚洲欧美重口味在线-欧美va免费在线观看