本文主要是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
當經過new操做符調用一個函數對象的時候,實際上會執行內部定義的[[Construct]]方法,下面從規範上理解[[Construct]]方法從而理解調用構造函數的實際行爲.
在經過new調用構造函數的時候會進行一些參數的修正而後調用構造函數的[[Construct]]
[[Construct]]主要分爲一下幾個步驟:github
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
複製代碼
ECMAScript2020
ECMAScript2016規範理解(8)-new表達式的執行過程
深刻理解javascript系列之執行環境ecmascript
歡迎你們關注公衆號,一塊兒進步async