Hibop.github.io
Hibop.github.io copied to clipboard
关于js引擎工作原理
var x = 1; // 定义一个全局变量 x
function foo(y) {
var x = 2; // 定义一个局部变量 x
function bar(z) { // 定义一个内部函数 B
console.log(x + y + z);
}
return bar; // 返回函数B的引用
}
var baz = foo(1); // 执行A,返回B
baz(1); // 执行函数B,输出 4
ECStack: 执行上下文栈 Execution Context Stack
EC: 执行上下文
VO: 变量对象(Varibale Object)
AO: 活动对象(Activation Object)
scopeChain: 作用域链(Scope Chain)
ECStack = [ //执行环境栈
EC(bar) = { //创建bar的执行环境,并处于作用域链的顶端
[scope]:AO(foo), //指向函数A的作用域链,AO(A)->VO(G)
var AO(bar) = { //创建函数bar的活动对象
z:1,
arguments:[],
this: window
}
scopeChain:<AO(bar), bar[[scope]]> //链表初始化为B[[scope]],再将AO(B)加入链表表头,此时B的作用域链:AO(B)->AO(A)-VO(G)
},
EC(foo)) = { // foo的执行环境
[scope]: VO(G), //VO是全局变量对象
AO(foo): { //创建函数A的活动对象
y: 1,
x: 2, //定义局部变量x
bar: function () {
...
}, //定义函数B
bar[[scope]] = this; // this指代AO本身,而AO位于scopeChain的顶端,因此B[[scope]]指向整个作用域链
arguments: [], //平时我们在函数中访问的arguments就是AO中的arguments
this: window //函数中的this指向调用者window对象
},
scopeChain: < AO(foo), foo[[scope]] > //链表初始化为A[[scope]],然后再把AO加入该作用域链的顶端,此时A的作用域链:AO(A)->VO(G)
},
EC(G) = { //全局执行环境
VO(G): { //创建全局变量对象
... //包含全局对象原有的属性
x = 1; //定义变量x
foo = function () {
...
}; //定义函数A
foo[[scope]] = this; //定义A的scope,A[[scope]] == VO(G)
}
}
];
参考文献 https://www.cnblogs.com/onepixel/p/5090799.html https://juejin.im/post/5c6bbf0f6fb9a049ba4224fd