作用域链

文章目录
  1. 1. 拓展: EC, VO
  2. 2. 练习

参考资料

// 定义一个全局的变量
var a = 'global var';

function foo () {
console.log(a);
}

foo(); // 输出a

foo.prototype.[[Scopes]]数组里会保存上级的作用域,这里保存了window的引用;当该变量在foo的栈中找不到时,会尝试在[[Scopes]][0]里寻找;如果上一级找不到,那么会继续尝试在上上级的[Scopes]][1]里寻找,一直到顶级作用域window,然后报错;这种链路称为作用域链

function outer () {
var a = 1;

function inner () {
var b = 2;
return () => {
console.log(a, b);
}
}

return inner();
}

outer()();

拓展: EC, VO

上面的[[Scopes]]保存了上级作用域的信息,而当前作用域的信息则保存在EC中【参考资料

  • 执行上下文(EC)
  • VO: 变量对象
function foo(i){
var a = 'hello'
var b = function(){}
function c(){}
}
foo(22)


// EC对象,保存当前栈执行的上下文信息
ECObj = {
scopChain: {...},
variableObject: { // VO,保存当前栈里的变量信息
arguments: {
0: 22,
length: 1
},
i: 22,
c: pointer to function c()
a: undefined,
b: undefined
},
this: { ... }
}

练习

var a = 1;
(function a () {
// a = 20; // 严格模式下会报错"Assignment to constant variable",普通模式会忽略
console.log(a); // function a {...}
console.log(window.a);
})();