ECMAScript規範解讀-函數對象

前言

本文主要是EcmaScript2020中一些基本概念的解讀,經過這些解讀來學習javascript在運行時的實際行爲.javascript

函數對象

函數對象是對外部的詞法環境和有必定入參的代碼進行封裝後的對象(閉包).函數對象的調用支持動態的綁定執行環境.在javascript函數執行的時候,其實是調用當前函數對象的一些內置方法來實現的.下面是函數對象的一些內部實現:java

內部實現 類型 描述
[[Environment]] Lexical Environment(詞法環境) 詞法環境定義當前函數對象生成時候的外部環境,例如引用的外部變量等
[[FormalParameters]] Parse Node 定義函數的參數列表
[[FunctionKind]] String 函數類型(normal, classConstructor, generator, async, async generator)
[[ECMAScriptCode]] Parse Node 代碼體
[[ConstructorKind]] String 構造類型,當函數經過new操做符進行調用的時候,會用到這個屬性.(base derived 繼承)
[[Realm]] Realm Record 當前函數對象的Realm記錄,在函數執行的時候須要將函數與Realm進行綁定,由Realm提供全局的環境對象等
[[ScriptOrModule]] Script Record or Module Record 記錄當前函數對象不一樣建立方式的記錄
[[ThisMode]] (lexical, strict, global) this會在進入函數的執行環境時進行綁定.lexical表明着this的肯定規則是由外部的詞法環境決定的(箭頭函數),strict表明this是由函數的調用者提供的,global表明着this由外部的全局對象指定(須要區分嚴格和非嚴格模式).
[[Strict]] Boolean 肯定當前函數是不是一個在嚴格模式下執行的函數

全部的EcmaScript函數對象在實現上有定義有[[Call]]這個內部方法,能夠被new調用的構造函數對象在實現上定義有[[Construct]]方法.git

規範詳細解讀

[[Construct]]

當經過new操做符調用一個函數對象的時候,實際上會執行內部定義的[[Construct]]方法,下面從規範上理解[[Construct]]方法從而理解調用構造函數的實際行爲.
在經過new調用構造函數的時候會進行一些參數的修正而後調用構造函數的[[Construct]]
newBefore
new
objCreate
[[Construct]]主要分爲一下幾個步驟:github

  1. 將執行上下文定義爲當前的執行上下文
  2. 獲取當前函數對象的[[ConstructorKind]], 若是是base類型, 將當前的執行環境的this設置爲以構造函數爲原型建立的對象
  3. 建立新的執行上下文將2中的this綁定到當前的執行上下文
  4. 在當前的詞法環境和環境記錄上執行構造函數
  5. 退出當前的執行上下文,返回到上次的執行上下文
  6. 若是執行構造函數的結果是有返回值的,當返回一個對象的時候直接將執行結果返回.當有返回結果可是不是對象的時候返回以前建立的this
  7. 沒有返回值的時候,返回以前建立的this.

簡單實現一個new的調用過程

function myNew(Con, ...args) {
  const obj = Object.create(Con.prototype);
  const ret = Con.call(obj, args);
  if(ret instanceof Object && ret !== null) {
    return ret;
  }
  return obj;
}
複製代碼

規範實例

[[Environment]]定義函數對象建立時候的外部詞法環境.實際上在javascript中函數就是閉包的概念.函數在建立的時候就已經跟外部的詞法環境進行了綁定,在調用的時候並不會改變函數的外部的詞法環境.bash

const a = 100;
function test() {
  console.log(a);
}
function test2() {
  const a = 200;
  test();
}
const obj = {
  a: function() {
    test();
  }
}
test2() // 100
obj.a(); // 100
複製代碼

對於this的肯定,能夠參考下面的肯定規則:
this閉包

參考

ECMAScript2020
ECMAScript2016規範理解(8)-new表達式的執行過程
深刻理解javascript系列之執行環境ecmascript

                                        

                                               歡迎你們關注公衆號,一塊兒進步async

相關文章
相關標籤/搜索