本文主要是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