js基礎梳理 究竟什麼是變數物件,什麼是活動物件?

2022-03-09 11:51:03 字數 2879 閱讀 4130

首先,回顧下上篇博文中js基礎梳理-究竟什麼是執行上下文棧(執行棧),執行上下文(可執行**)?的執行上下文的生命週期:

3.1 建立階段

3.2 執行階段

在寫程式的時候會定義很多變數和函式,那js解析器是如何找到這些變數和函式的?

變數物件是與執行上下文對應的概念,在執行上下文的建立階段,它依次儲存著在上下文中定義的以下內容:

1.1函式的所有形參(如果是函式上下文中):

建立arguments物件。檢查當前上下文中的引數,建立該物件下的屬性與屬性值。沒有實參的話,屬性值為undefined。

1.2.所有函式宣告:(functiondeclaration, fd)

檢查當前上下文的函式宣告,也就是使用function關鍵字宣告的函式。在變數物件中以函式名建立乙個屬性,屬性值為指向該函式所在記憶體位址的引用。如果變數物件已經存在相同名稱的屬性,則完全替換這個屬性。

1.3.所有變數宣告:(var, variabledeclaration)

檢查當前上下文中的變數宣告,每找到乙個變數宣告,就在變數物件中以變數名建立乙個屬性,屬性值為undefined。如果變數名稱跟已經宣告的形式引數或函式相同,則變數宣告不會干擾已經存在的這類屬性。

未進入執行階段前,變數物件中的屬性都不能訪問!但是進入到執行階段之後,變數物件轉變成了活動物件,裡面的屬性都能被訪問了,然後開始進行執行階段的操作。

因此,對於函式上下文來講,活動物件與變數物件其實都是同乙個物件,只是處於執行上下文的不同生命週期。不過只有處於執行上下文棧棧頂的函式執行上下文中的變數物件,才會變成活動物件。

說了一堆概念,有點懵,對嗎?請看這個例子:

var a = 10;

function b () ;

function bar(a, b)

console.log('2', a, b)

}bar(2, 3)

console.log('3', a, b)

要想知道為什麼會這樣列印,首先,從執行上下文的建立階段來分析變數物件:

// 建立階段:

// 第一步,遇到了全域性**,進入全域性上下文,此時的執行上下文棧是這樣

ecstack = [

globalcontext:

}];// 第二步,發現bar函式被呼叫,就又建立了乙個函式上下文,此時的執行上下文棧是這樣

ecstack = [

globalcontext:

},functioncontext: ,

a: 2,

// b: 3,

// 根據1.2, 再分析bar函式中的函式宣告b,並且賦值為b函式所在記憶體位址的引用, 它發現vo中已經有b:3了,就會覆蓋掉它。因此上面一行中的b:3實際上不存在了。

b: // 根據1.3,接著分析bar函式中的變數宣告a,並且賦值為undefined, 但是發現vo中已經有a:2了,因此下面一行中的a:undefined也是會不存在的。

// a: undefined}}

]

以上就是執行上下文中的**分析階段,也就是執行上下文的建立階段。再看看執行上下文的**執行階又發生了什麼。

// 執行階段:

// 第三步:首先,執行了bar(2, 3)函式,緊接著,在bar函式裡執行了console.log('1', a, b)。全域性上下文中依然還是vo,但是函式上下文中vo就變成了ao。並且**執行到這,就已經修改了全域性上下文中的變數a.

ecstack = [

globalcontext:

},functioncontext: ,

a: 2,

b: }

}]// 因此會輸出結果: '1', 2, function b() ;

// 第四步:執行console.log('2', a, b)的時候, 發現裡面的變數a被重新賦值為1了。

ecstack = [

globalcontext:

},functioncontext: ,

a: 1,

b: }

}]// 因此會輸出結果: '2', 1, function b() ;

// 第五步,執行到console.log('3', a, b)的時候,ecstack發現bar函式已經執行完了,就把bar從ecstack給彈出去了。此時的執行上下文棧是這樣的。

ecstack = [

globalcontext:

}]// 因此會輸出結果: '3', 10, function b()

總結一下,變數物件會有以下四種特性:

全域性上下文的變數物件初始化是全域性物件(其實這篇文章並沒有介紹這個特性,不過它也很簡單就這麼一句話而已)

函式上下文的變數物件初始化只包括arguments物件

在進入執行上下文的時候會給變數物件新增形參,函式宣告,變數宣告等初始的屬性值

在**執行階段,會再次修改變數物件的屬性值。

理解了這些,是不是發現再有一些函式提公升,變數提公升什麼的是不是都很簡單了。例如,你可以思考下這三段**分別發生了什麼。

foo() 

var foo = function()

function foo()

foo() 

function foo()

var foo = function()

var foo = function() 

function foo()

foo()

JS基礎知識梳理 location 物件

一 簡介 location物件是乙個較為特別的物件,既是window物件的屬性也是document物件的屬性。location物件的用處不僅僅表現在儲存著當前文件的資訊,還能將url解析成獨立的片段。location.port 返回當前伺服器的埠號,如果不存在,返回空值 location.hostn...

web前端基礎 什麼是物件

英文 object 計算機業界現在已經習慣翻譯為 物件 口語化一些,中文的意思就是 事物 事物 這個詞有點抽象,你當然可以具體到人,或是具體到交通工具。人可以再具體一些,學生?工人?如果是學生,叫什麼名字?每個事物都有一些特點,人有身高,體重,在程式中我們稱之為屬性 還可以有一些行為,人要吃飯,睡覺...

js函式中this是全域性變數還是當前物件

問題 在web專案前端實現時,有兩個小功能模組,一方面想自我要求必須物件導向的方式實現,另一方面此功能模組沒有相同的模式,不需要用類多次例項化,因此建立乙個單例是最好的選擇。單例的js實現有多種方式 1.以物件實現 var singleton func2 function 缺陷是沒有建構函式,不能執...