词法作用域(静态作用域)与动态作用域的区别是什么?
请说明词法作用域和动态作用域的区别,并举例 JavaScript 为何属于词法作用域。
回答
小字辈
词法作用域(Lexical/Static Scope):函数的作用域在定义时决定,取决于源代码中函数的嵌套位置。
动态作用域(Dynamic Scope):函数的作用域在调用时决定,取决于函数调用的栈(call stack)。
JavaScript 示例:
let x = 1;
function foo() {
console.log(x);
}
function bar() {
let x = 2;
foo();
}
bar(); // 输出 1(词法作用域),如果 JS 是动态作用域则应输出 2
关键区别:
- 词法作用域看函数在哪里定义,作用域链在编码时确定
- 动态作用域看函数在哪里调用,作用域链在运行时确定
this 的相似之处:虽然 JS 是词法作用域,但 this 的绑定类似于动态作用域(取决于调用方式),这也是初学者常把 this 和作用域混淆的原因。箭头函数修复了这一点,其 this 由词法作用域决定。