最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解JavaScript?變量對象

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

前言

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

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

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

今天我們來重點講解變量對象。

變量對象

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

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

全局上下文中變量對象

全局上下文中的變量對象是全局對象。

下面我們來了解一下全局對象,在 W3school 中的介紹有:

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

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

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

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

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

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

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

在函數(shù)上下文中,我們用活動對象(activation object, AO)來表示變量對象。

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

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

執(zhí)行過程

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

預(yù)編譯

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

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

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

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

我們來看個例子:

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

  b = 3;
}

foo(1);

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

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

代碼執(zhí)行

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

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

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

總結(jié)

至此,變量對象的創(chuàng)建過程我們就介紹完了,我們來做個總結(jié):

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

練習(xí)題

  • 第一題

來看下面兩端代碼,分別會打印什么?

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

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

第一段會報錯:Uncaught ReferenceError: a is not defined。

第二段會打印:1。

因為第一段代碼 a 沒有變量聲明,所以函數(shù)執(zhí)行上下文的 AO 中沒有 a 變量的定義,此時 AO 的值是:

AO = {
    arguments: {
        length: 0
    }
}

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

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

  • 第二題
console.log(foo);

function foo() {}

var foo = 1;

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

因為在預(yù)編譯的第 4 步,會尋找函數(shù)聲明,值為函數(shù)體,也就是函數(shù)聲明會覆蓋變量聲明。

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

相關(guān)文章

  • 如何使用原生Js實現(xiàn)隨機點名詳解

    如何使用原生Js實現(xiàn)隨機點名詳解

    這篇文章主要給大家介紹了關(guān)于如何使用原生Js實現(xiàn)隨機點名的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • js的Object.assign用法示例分析

    js的Object.assign用法示例分析

    這篇文章主要介紹了js的Object.assign用法,結(jié)合實例形式分析了js Object.assign基本功能、原理、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下
    2020-03-03
  • 淺談JavaScript的函數(shù)及作用域

    淺談JavaScript的函數(shù)及作用域

    函數(shù)和作用域是JavaScript的重要組成部分,我們在使用JavaScript編寫程序的過程中經(jīng)常要用到這兩部分內(nèi)容,借助此文一起來鞏固下學(xué)習(xí)的內(nèi)容吧。
    2016-12-12
  • 基于bootstrap實現(xiàn)廣告輪播帶圖片和文字效果

    基于bootstrap實現(xiàn)廣告輪播帶圖片和文字效果

    這篇文章主要介紹了基于bootstrap實現(xiàn)廣告輪播帶圖片和文字效果,效果非常棒,需要的朋友可以參考下
    2016-07-07
  • JS+HTML5 FileReader實現(xiàn)文件上傳前本地預(yù)覽功能

    JS+HTML5 FileReader實現(xiàn)文件上傳前本地預(yù)覽功能

    這篇文章主要為大家詳細介紹了JS+HTML5 FileReader實現(xiàn)文件上傳前本地預(yù)覽功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • javascript截取字符串(通過substring實現(xiàn)并支持中英文混合)

    javascript截取字符串(通過substring實現(xiàn)并支持中英文混合)

    用js方法substring()、方法substr()實現(xiàn)如標題所示的截取字符串并支持中英文混合,具體代碼如下,感興趣的各位可以參考下哈
    2013-06-06
  • 利用函數(shù)的惰性載入提高javascript代碼執(zhí)行效率

    利用函數(shù)的惰性載入提高javascript代碼執(zhí)行效率

    在 addEvent 函數(shù)每次調(diào)用的時候都要走一遍,如果瀏覽器支持其中的一種方法,那么他就會一直支持了,就沒有必要再進行其他分支的檢測了
    2014-05-05
  • js中的閉包實例展示

    js中的閉包實例展示

    閉包是js中的一大特色,也是一大難點。下面這篇文章主要給大家介紹了關(guān)于js中閉包的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-11-11
  • 區(qū)分中英文字符的兩種方法(正則和charCodeAt())

    區(qū)分中英文字符的兩種方法(正則和charCodeAt())

    最近在為項目寫登錄注冊系列頁面, 表單驗證無疑是不可缺少的部分, 在這個jQ插件滿天飛的web年代, 表單驗證倒也不是難事. 但再好的插件, 也并不能做到十全十美
    2010-11-11
  • JavaScript cookie原理及使用實例

    JavaScript cookie原理及使用實例

    這篇文章主要介紹了JavaScript cookie原理及使用實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05

最新評論

澜沧| 弥勒县| 台山市| 文化| 昌黎县| 罗甸县| 万荣县| 阜南县| 探索| 昌黎县| 大冶市| 合川市| 凤山市| 新营市| 宜昌市| 获嘉县| 弥渡县| 泽州县| 福海县| 谷城县| 青浦区| 香港| 通化县| 应用必备| 建昌县| 响水县| 思茅市| 温宿县| 鄂州市| 文山县| 广西| 鄢陵县| 田林县| 建水县| 札达县| 曲周县| 井陉县| 涞水县| 科技| 太康县| 靖宇县|