再看javascript執行內容、變數對象

來源:互聯網
上載者:User

標籤:函數對象   建立   一段   出錯   efi   存在   mit   val   table   

突然看到一篇遠在2010年的老文,作者以章節的形式向我們介紹了ECMA-262-3的部分內容,主要涉及到執行內容、變數對象、範圍、this等語言細節。內容短小而精悍,文風直白而嚴謹,讀完有酣暢淋漓、醍醐灌頂之感,強烈推薦!!!

原文連結:這裡

本想翻譯成文,原來早已有人做了,這裡。真生不逢時,何其遺憾啊!

做個筆記,聊慰我心。執行內容 ExecutionContext

每當控制器(control)轉換到ECMAScript可執行代碼時,都會建立並進入到一個可執行內容。

一段簡短的句子,卻包含著豐富的內容:

  • 控制器:即js引擎
  • 轉換:從一段可執行代碼跳轉到另一段可執行代碼
  • 可執行代碼:全域代碼、函數代碼、eval代碼(分別對應三種範圍)
  • 執行內容:是一個抽象的概念,ECMA-262標準用這個概念同可執行代碼(executable code)概念進行區分

執行內容在邏輯上組成一個堆棧。堆棧底部永遠都是全域上下文(global context),堆棧頂部是當前/活動的執行內容(activeExecutionContext)。堆棧在EC類型的變數(various kingds of EC)被推入或彈出的同時被修改。

例如,我們可以定義一個數組來類比執行內容堆棧:

ECStack = [  globalContext,  <foo> functionContext]
變數對象 VariableObject

變數對象(VO)作為執行內容的一個屬性存在,它儲存下列內容:

  • 所有變數聲明 (var, VariableDeclaration)
    • VO的一個屬性,這個屬性由變數名稱和undefined值組成;如果變數名稱跟已經聲明的形式參數或函數相同,則變數聲明不會干擾已經存在的這類屬性。
  • 函式宣告 (FunctionDeclaration, 縮寫為FD)
    • VO的一個屬性,這個屬性由一個函數對象(function-object)的名稱和值組成;如果變數對象已經存在相同名稱的屬性,則完全替換這個屬性。
  • 以及函數的形參
    • VO的一個屬性,這個屬性由一個形式參數的名稱和值組成;如果沒有對應傳遞實際參數,那麼這個屬性就由形式參數的名稱和undefined值組成;
    VO = {  // context data (var, FD, function arguments)}

    當我們聲明一個變數或一個函數的時候,同時還用變數的名稱和值在VO裡建立了一個新的屬性。
    例如:

    var m = 30;function test(a,b) {var c = 20function d() {}var e = function _e() {};}test(10)

    當進入“test”函數的上下文時(傳遞參數10),AO如下:

    AO(test) = {a: 10,b: undefined,c: undefined,d: <reference to FunctionDeclaration "d">e: undefined};

    test執行到最後時,對應此刻上下文堆棧:

    ECStack = [globalContext: {  VO: {    m: 30,    test:   }},test functionContext: {  VO: {    a: 10,    b: undefined,    c: 20,    d: <reference to FunctionDeclaration "d">,    e: <reference to FunctionDeclaration "_e">  }}]
    關於變數

    通常,各類文章和JavaScript相關的書籍都聲稱:“不管是使用var關鍵字(在全域上下文)還是不使用var關鍵字(在任何地方),都可以聲明一個變數”。請記住,這絕對是謠傳:任何時候,變數只能通過使用var關鍵字才能聲明。

讓我們通過下面的執行個體看看具體的區別吧:

alert(a); // undefinedalert(b); // "b" is not defined b = 10;var a = 20;

所有根源仍然是VO和它的修改階段(進入上下文階段和執行代碼階段):

VO = {  a: undefined};

我們可以看到,因為“b”不是一個變數,所以在這個階段根本就沒有“b”,“b”將只在執行代碼階段才會出現(但是在我們這個例子裡,還沒有到那就已經出錯了)。

讓我們改變一下例子代碼:

alert(a); // undefined, we know why b = 10;alert(b); // 10, created at code execution var a = 20;alert(a); // 20, modified at code execution

關於變數,還有一個重要的知識點。變數相對於簡單屬性來說,變數有一個特性(attribute):{DontDelete},這個特性的含義就是不同通過delete操作符直接刪除變數屬性。

a = 10;alert(window.a); // 10 alert(delete a); // true alert(window.a); // undefined var b = 20;alert(window.b); // 20 alert(delete b); // false alert(window.b); // still 20

2018-8-2-再看執行內容、變數對象

再看javascript執行內容、變數對象

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.