题目 03 / 14
函数读取的是调用者的变量,还是定义时所在作用域的变量?
知识点: 词法作用域
JavaScript 采用词法(静态)作用域,函数的作用域链在定义时就已确定,与谁调用它无关。
使用执行可视化器解题在下方逐步观察每个绑定、函数调用和控制台输出。预测输出结果
预测输出结果。foo 在 bar 内部执行时,读取的是外层 x,还是 bar 的局部 x?
var x = 10;
function foo() {
console.log(x);
}
function bar() {
var x = 20;
foo();
}
bar();查看答案与完整解析
正确输出
10为什么会这样
foo 和 bar 都声明在全局作用域,因此 foo 的外部环境引用始终指向全局环境,无论是谁调用了 foo。
调用 bar() 会创建自己的局部 x,值为 20,但这个绑定只存在于 bar 自己的环境中,从未加入 foo 的作用域链。
在 bar() 内部调用 foo() 时,foo 仍然沿着自己的作用域链查找 x:先局部(没有),再全局,找到值为 10 的 x。调用位置不会改变这条作用域链,因此输出结果是 10。
这道题考察什么
- 词法作用域
- 作用域链在定义时确定,而非调用时
- JavaScript 没有动态作用域
运行环境前提
这是任意 JavaScript 环境下标准的词法作用域行为;JavaScript 从不使用动态作用域。