面试题答案
一键面试作用域链在主表达式求值中的作用
- 对象字面量表达式:对象字面量本身不创建新的作用域。在对象字面量中定义的属性和方法,其作用域链主要取决于它们定义时所在的外部作用域。例如:
let outerVar = 'outer';
let obj = {
innerProp: outerVar,
innerFunc: function() {
return this.innerProp;
}
};
console.log(obj.innerFunc());// 'outer'
这里obj
的属性innerProp
和方法innerFunc
可以访问到外部作用域的outerVar
,因为它们的作用域链向上查找时能找到定义outerVar
的外部作用域。
- 函数表达式:函数表达式创建一个新的函数作用域。在函数内部,作用域链首先包含函数自身的作用域(用于存储局部变量和参数),然后向上链接到定义该函数的外部作用域。例如:
let globalVar = 'global';
let funcExp = function() {
let localVar = 'local';
console.log(globalVar);
console.log(localVar);
};
funcExp();
// 'global'
// 'local'
在funcExp
函数内部,它可以访问到自身的局部变量localVar
以及外部作用域的globalVar
,通过作用域链依次查找。
嵌套函数与作用域链的动态变化
当内部函数引用了外部函数的变量时,作用域链会动态变化。内部函数会形成一个闭包,其作用域链包含自身作用域、外部函数作用域以及外部函数的外部作用域等,直到全局作用域。例如:
function outerFunction() {
let outerVar = 'outer';
function innerFunction() {
return outerVar;
}
return innerFunction;
}
let innerFunc = outerFunction();
console.log(innerFunc());// 'outer'
在上述代码中,innerFunction
定义在outerFunction
内部,当outerFunction
执行并返回innerFunction
后,outerFunction
的执行上下文理论上应该被销毁,但由于innerFunction
引用了outerFunction
的outerVar
,outerFunction
的作用域不会被销毁,innerFunction
的作用域链依然保持对outerFunction
作用域的引用,从而可以访问到outerVar
。这体现了作用域链在嵌套函数且有变量引用情况下的动态保持与作用。