我对javascript具有词汇范围感到困惑。
词法作用域:词法作用域是指您定义函数的范围内的任何变量(而不是何时调用它(都在函数的作用域中。
然而,在JS中,它:在定义和编译函数时不分配范围,而是在运行时分配,即调用函数时
在下面的示例中:如果 JS 具有词法范围,我会得到一个错误。但是我没有,因为提升和运行时 js 引擎检查 x。
function f() {
console.log(x);
}
const x = 10;
f(); // 10
有人可以用一个例子解释JS如何具有词汇范围吗?谢谢!
但是在JS中,它: 范围不是在定义和编译函数时分配的,而是在运行时分配的,即当调用函数时
我认为您对 JS 中的这种范围描述感到困惑。本文对JS中的范围进行了更准确的描述(强调(:
因为函数也是在这个时候定义的(词法阶段(,我们可以说词法范围是基于创作时变量和范围块存在的位置,因此在词法分析阶段结束时被锁定。作用域不是在运行时定义的,而是可以在运行时访问的。
因此,在您的示例中:
function f() {
console.log(x);
}
const x = 10;
f(); // 10
正在发生的事情是,函数f
的作用域链由以下部分组成:
- 其本地范围
- 外部,全球范围
而这个"作用域链"是在创作时定义的(即词汇作用域(。
在创作时,常量x
在全局范围内定义,调用f
时,x
在全局范围内可用。声明(但未调用(函数f
时未定义x
与本次讨论无关。
此外,当您在代码示例中提到"提升"时,您是不正确的:用const
声明的变量不会被提升。
如果我们更改您的示例,我们将得到一个引用错误,因为常量x
尚未在全局范围内初始化(即在创作时(,当调用函数f
时(并且函数f
查看其作用域链,该范围链已在创作时定义(:
function f() {
console.log(x);
}
f(); // 10
const x = 10;
参见下面的示例,函数f
之外的所有内容都被编译并提升了 var。 但是函数f
中的内容在被调用之前不会被提升/解析。并且f
函数中的局部变量仍然可以访问(即函数的词法范围(。
function f() {
console.log(x);
var a = 20;
}
const x = 10;
f(); // 10
console.log(a);