JavaScript - 词法作用域
什么是词法作用域?
词法作用域是指表达式的定义区域。换句话说,一个项的词法作用域是它生成的上下文。
词法作用域有时也称为静态作用域。一个项的词法作用域并不总是由其调用的位置决定。对象的词法作用域充当其定义空间。
因此,您可能知道变量和方法具有不同级别的作用域 -
全局作用域:在任何函数或块之外定义但可在整个程序范围内访问的变量。
局部作用域:在函数或块内定义且只能在该函数或块内访问的变量被视为局部作用域。
嵌套作用域:内部函数可以访问其父函数中的变量。
块作用域:使用 let 和 const 定义的变量仅在声明它们的块中有效,例如循环或条件语句。
现在,让我们在下面的部分中查看 JavaScript 中词法作用域的一些示例。
示例1
让我们看看下面的示例代码 -
// 在全局范围内定义一个变量
const myName = "Shwetaa";
// 从函数中调用 myName 变量
function getName() {
return myName;
}
在上面的示例代码中,我们在全局作用域中定义了 myName 变量,并在 getName() 函数中使用它。
那么问题来了:这两个空间中的哪一个涵盖了 myName 的词法作用域?是 getName() 函数的全局作用域还是局部作用域?
因此,您必须记住,词法作用域指的是定义空间,而不是调用空间。由于我们在全局环境中定义了 myName,因此它的词法作用域是全局的。
示例 2
让我们看另一个 JavaScript 词法作用域的示例 -
function getName() {
const myName = "Swati";
return myName;
}
那么问题来了:myName 的词法作用域在哪里?
答案是:注意我们在 getName() 中是如何定义和调用 myName 的。因此,myName 的词法作用域是 getName() 的局部环境,也就是 myName 的定义空间。
词法作用域如何工作?
可以访问 JavaScript 表达式的代码取决于它定义的环境。
换句话说,只有位于某个项的词法作用域内的代码才能访问它。例如,以下代码:
// 定义一个函数
function myLastName() {
const lastName = "Sharma";
return lastName;
}
// 定义另一个函数
function showFullName() {
const fullName = "Swati " + lastName;
return fullName;
}
// 调用 showFullName():
console.log(showFullName());
输出
上述调用将返回 −
Uncaught ReferenceError: lastName is not defined
请注意,上一个代码片段对 showFullName() 的调用导致了 Uncaught ReferenceError。返回该错误是因为该项只能由其词法作用域内的代码访问。
因此,showFullName() 函数及其内部代码无法访问 lastName 变量,因为它是在不同的作用域中定义的。换句话说,lastName 的词法作用域与 showFullName() 的词法作用域不同。
LastName 的定义空间是 showLastName(),而 showFullName() 的词法作用域是全局环境。
现在,请看下面的代码 −
function showLastName() {
const lastName = "Sharma";
return lastName;
}
// 定义另一个函数:
function displayFullName() {
const fullName = "Swati " + showLastName();
return fullName;
}
// 调用 displayFullName():
console.log(displayFullName());
displayFullName;
这将生成以下结果 -
Swati Sharma
由于 showFullName() 和 showLastName() 位于同一词法作用域,因此在上面的示例中它们都返回了"Swati Sharma"。
换句话说,由于这两个过程编写在同一个全局作用域中,showFullName() 可能会调用 showLastName()。
总结
理解 JavaScript 中的词法作用域对于创建简洁、可维护的代码至关重要。通过合理地限定变量和函数的作用域,你可以最大限度地减少命名冲突,提高代码的可读性,并避免不良影响。理解词法作用域可以使程序更加有序、高效。

