JS执行上下文
V8解析JS代码后,先编译生成上下文,再运行。
调用栈
- 编译代码,生成全局上下文
- 进入函数后,创建运行上下文,函数结束后销毁
- 进入eval后,创建运行上下文
运行前将全局上下文压入调用栈。遇到函数时创建函数运行上下文并压栈。函数结束后出栈销毁。
爆栈:递归次数过万时调用栈溢出。V8中尾递归也会爆栈(Safari中优化为迭代不会)。
ES6箭头函数不创建自己的执行上下文。
作用域链
变量环境中有一个 outer 引用,指向外部执行环境。变量未在当前环境找到时,沿outer链查找。
关键:作用域链由词法作用域决定,与运行时无关。
// foo定义在全局,outer指向全局 → 输出 global
function foo() { console.log(title); }
function bar() { var title = 'bar'; foo(); }
var title = 'global';
bar(); // global
// foo定义在bar内部,outer指向bar → 输出 bar
function bar() {
function foo() { console.log(title); }
var title = 'bar';
foo(); // bar
}