欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解JavaScript?變量對(duì)象

 更新時(shí)間:2022年05月23日 08:31:19   作者:小寶的挖機(jī)  
變量對(duì)象是與執(zhí)行上下文相關(guān)的數(shù)據(jù)作用域,存儲(chǔ)了在上下文中定義的變量和函數(shù)聲明,本文主要介紹了JavaScript?變量對(duì)象,具有一定的參考價(jià)值,感興趣的可以了解一下

前言

在上節(jié)《深入 JavaScript 執(zhí)行上下文棧——Web 前端進(jìn)階系列第三節(jié)》我們講到,JavaScript 引擎執(zhí)行一段可執(zhí)行代碼時(shí),會(huì)創(chuàng)建對(duì)應(yīng)的執(zhí)行上下文。

對(duì)于每個(gè)執(zhí)行上下文,都有三個(gè)重要屬性:

  • 變量對(duì)象(Variable object,VO)
  • 作用域鏈(Scope chain)
  • this

今天我們來(lái)重點(diǎn)講解變量對(duì)象。

變量對(duì)象

變量對(duì)象是與執(zhí)行上下文相關(guān)的數(shù)據(jù)作用域,存儲(chǔ)了在上下文中定義的變量和函數(shù)聲明。

執(zhí)行上下文分為兩種:全局上下文和函數(shù)上下文,接下來(lái)我們來(lái)分別講解這兩種上下文的變量對(duì)象。

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

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

下面我們來(lái)了解一下全局對(duì)象,在 W3school 中的介紹有:

  • 全局對(duì)象是預(yù)定義的對(duì)象,作為 JavaScript 的全局函數(shù)和全局屬性的占位符。通過(guò)使用全局對(duì)象,可以訪問(wèn)所有其他預(yù)定義的對(duì)象、函數(shù)和屬性。

  • 在頂層 JavaScript 代碼中,可以用關(guān)鍵字 this 引用全局對(duì)象。全局對(duì)象在作用域鏈最底端,這意味著所有非限定性的變量和函數(shù)名都會(huì)作為該對(duì)象的屬性來(lái)查詢。

  • 由于全局對(duì)象在作用域鏈最底端,這也意味著在頂層 JavaScript 代碼中聲明的變量都將成為全局對(duì)象的屬性。

字面上大家理解起來(lái)可能比較抽象,接下來(lái)我們結(jié)合具體例子作進(jìn)一步講解。

  • 在頂層 JavaScript 代碼中,可以用關(guān)鍵字 this 引用全局對(duì)象。在瀏覽器 JavaScript 中,全局對(duì)象是 window。在 node.js 中,全局對(duì)象是 global。
console.log(this); // window
console.log(this === window); // true
  • 全局對(duì)象是 JavaScript 的全局函數(shù)和全局屬性的占位符。在頂層 JavaScript 代碼中聲明的變量都將成為全局對(duì)象的屬性。
// 聲明的變量成為了全局對(duì)象的屬性
var a = 1;
console.log(this.a); // 1

// 聲明的函數(shù)成為了全局對(duì)象的屬性
function b() {}
console.log(this.b); // function b
  • 通過(guò)使用全局對(duì)象,可以訪問(wèn)全局函數(shù)和全局屬性,也可以訪問(wèn)所有其他預(yù)定義的對(duì)象、函數(shù)和屬性。
// 使用全局對(duì)象訪問(wèn)全局屬性 Math,它是一個(gè)對(duì)象,它擁有 random 方法。
console.log(this.Math.random()); // 打印一個(gè)隨機(jī)數(shù)
  • 所有非限定性的變量和函數(shù)名都會(huì)作為該對(duì)象的屬性來(lái)查詢。
// 這里的 Math 是非限定性的函數(shù)名
console.log(Math.random()); // 打印一個(gè)隨機(jī)數(shù)
  • 全局對(duì)象是 Object 構(gòu)造函數(shù)的實(shí)例,這也意味著 Object.prototype(原型)上預(yù)定義的屬性和方法,是可以通過(guò)全局對(duì)象訪問(wèn)到的。
console.log(this instanceof Object); // true
  • 在瀏覽器 JavaScript 中,全局對(duì)象有 window 屬性且指向自身。
console.log(this.window === this); // true

函數(shù)上下文中的變量對(duì)象

在函數(shù)上下文中,我們用活動(dòng)對(duì)象(activation object, AO)來(lái)表示變量對(duì)象。

活動(dòng)對(duì)象和變量對(duì)象其實(shí)是一個(gè)東西,只是變量對(duì)象是規(guī)范上的或者說(shuō)是引擎實(shí)現(xiàn)上的,不可在 JavaScript 環(huán)境中訪問(wèn),只有到當(dāng)進(jìn)入一個(gè)執(zhí)行上下文中,這個(gè)執(zhí)行上下文的變量對(duì)象才會(huì)被激活,所以才叫 activation object,而只有被激活的變量對(duì)象,也就是活動(dòng)對(duì)象,各種屬性和方法才能被訪問(wèn)。

活動(dòng)對(duì)象是在進(jìn)入函數(shù)上下文時(shí)被創(chuàng)建的,它有函數(shù)的 arguments 屬性作為初始化屬性。arguments 屬性的值就是 Arguments 對(duì)象。

執(zhí)行過(guò)程

函數(shù)上下文的代碼執(zhí)行過(guò)程共分成兩個(gè)階段,分別是:預(yù)編譯和執(zhí)行。

預(yù)編譯

  • 創(chuàng)建 AO 對(duì)象,尋找形參和變量聲明

  • 把形參和變量名作為 AO 對(duì)象的屬性名,值為 undefined

  • 把實(shí)參賦給形參,實(shí)參形參相統(tǒng)一

  • 尋找函數(shù)聲明,值為函數(shù)體

我們來(lái)看個(gè)例子:

function foo(a) {
  var b = 2;
  function c() {}
  var d = function() {};

  b = 3;
}

foo(1);

這個(gè)函數(shù)在預(yù)編譯完成后,AO 會(huì)變?yōu)椋?/p>

AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: undefined,
    c: reference to function c(){},
    d: undefined
}

代碼執(zhí)行

在代碼執(zhí)行階段,會(huì)順序執(zhí)行代碼。根據(jù)代碼,修改變量對(duì)象的值。

上面的例子當(dāng)代碼執(zhí)行完,AO 會(huì)變?yōu)椋?/p>

AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: 3,
    c: reference to function c(){},
    d: reference to FunctionExpression "d"
}

總結(jié)

至此,變量對(duì)象的創(chuàng)建過(guò)程我們就介紹完了,我們來(lái)做個(gè)總結(jié):

  • 全局上下文的變量對(duì)象初始化是全局對(duì)象
  • 函數(shù)上下文的變量對(duì)象初始化只包括 Arguments 對(duì)象
  • 在進(jìn)入執(zhí)行上下文時(shí)會(huì)給變量對(duì)象添加形參、變量聲明、函數(shù)聲明等初始的屬性值(預(yù)編譯)
  • 在代碼執(zhí)行階段,會(huì)修改變量對(duì)象的屬性值

練習(xí)題

  • 第一題

來(lái)看下面兩端代碼,分別會(huì)打印什么?

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

foo();
function bar() {
  a = 1;
  console.log(a);
}
bar();

第一段會(huì)報(bào)錯(cuò):Uncaught ReferenceError: a is not defined。

第二段會(huì)打?。?。

因?yàn)榈谝欢未a a 沒(méi)有變量聲明,所以函數(shù)執(zhí)行上下文的 AO 中沒(méi)有 a 變量的定義,此時(shí) AO 的值是:

AO = {
    arguments: {
        length: 0
    }
}

執(zhí)行打印時(shí),在函數(shù)執(zhí)行上下文的 AO 中沒(méi)有找到 a 變量的定義,然后就會(huì)去全局上下文中找,發(fā)現(xiàn)全局也沒(méi)有,所以就會(huì)報(bào)未定義的錯(cuò)。

第二段代碼,沒(méi)有使用 var 關(guān)鍵字聲明的變量會(huì)成為全局對(duì)象的屬性,所以執(zhí)行打印時(shí),會(huì)從全局對(duì)象找到 a 的值,所以會(huì)打印 1。

  • 第二題
console.log(foo);

function foo() {}

var foo = 1;

會(huì)打印 foo 函數(shù),而不是 undefined。

因?yàn)樵陬A(yù)編譯的第 4 步,會(huì)尋找函數(shù)聲明,值為函數(shù)體,也就是函數(shù)聲明會(huì)覆蓋變量聲明。

到此這篇關(guān)于深入理解JavaScript 變量對(duì)象的文章就介紹到這了,更多相關(guān)JavaScript 變量對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論