面试题答案
一键面试执行上下文的创建过程
- 创建阶段:
- 确定this的值:根据函数的调用方式确定this的指向。例如在全局执行上下文中,this指向全局对象(在浏览器中是window,在Node.js中是global);在函数作为对象方法调用时,this指向该对象。
- 创建词法环境:词法环境包含一个环境记录和一个外部词法环境引用。环境记录用于存储变量声明、函数声明等。对于函数执行上下文,还会创建一个形参的环境记录。例如:
在这个function add(a, b) { let sum = a + b; return sum; }
add
函数执行上下文创建时,词法环境中的环境记录会包含a
、b
形参,以及内部声明的sum
变量。- 创建变量环境:在ES6之前,变量环境和词法环境基本相同。ES6之后,变量环境专门用于存储用
var
声明的变量,词法环境用于存储用let
和const
声明的变量、函数声明等。例如:
在全局执行上下文中,变量环境存储var num1 = 10; let num2 = 20; function test() { var num3 = 30; let num4 = 40; }
num1
,词法环境存储num2
;在test
函数执行上下文中,变量环境存储num3
,词法环境存储num4
。 - 激活/执行阶段:
- 变量赋值,函数引用被赋值,代码开始执行。例如在上述
add
函数中,a
、b
形参被传入实际值,sum
变量被赋值计算结果。
- 变量赋值,函数引用被赋值,代码开始执行。例如在上述
作用域链的构建
- 每个执行上下文都有一个与之关联的词法环境,词法环境有一个外部词法环境引用。
- 作用域链是由当前执行上下文的词法环境和所有祖先执行上下文的词法环境组成的链表。例如:
在function outer() { let outerVar = 'outer value'; function inner() { let innerVar = 'inner value'; console.log(outerVar); } inner(); } outer();
inner
函数执行上下文中,作用域链首先包含inner
函数自身的词法环境(包含innerVar
),然后是outer
函数的词法环境(包含outerVar
),最后是全局词法环境。所以inner
函数可以访问到outerVar
,因为沿着作用域链可以找到它。