返回

作用域链:弄懂作用域闭关锁国的秘诀

前端

在计算机编程中,作用域是指程序中变量的可见性。作用域决定了变量可以在哪里被访问和使用。作用域链是指变量在不同作用域中查找变量值的顺序。

在 JavaScript 中,有三种主要的作用域:

  • 全局作用域:全局作用域是整个程序可以访问的作用域。全局作用域中的变量可以在程序中的任何位置访问和使用。
  • 函数作用域:函数作用域是函数内部的作用域。函数作用域中的变量只能在函数内部访问和使用。
  • 块级作用域:块级作用域是使用 letconst 声明的变量的作用域。块级作用域中的变量只能在声明它们的块内访问和使用。

作用域链是变量在不同作用域中查找变量值的顺序。作用域链从当前作用域开始,然后向上查找父作用域,依次类推,直到找到变量的定义或到达全局作用域。

作用域链可以帮助我们理解为什么变量在某些情况下可以访问,而在其他情况下却不能访问。例如,如果一个变量在函数作用域中声明,那么它只能在该函数内部访问。但是,如果该变量在全局作用域中声明,那么它可以在程序中的任何位置访问。

作用域链还可以在我们查找变量的定义时帮助我们。例如,如果我们在一个函数中使用了一个变量,但我们不知道该变量在哪里声明,那么我们可以沿着作用域链向上查找,直到找到该变量的定义。

作用域和作用域链是 JavaScript 中的重要概念。理解作用域和作用域链可以帮助我们编写出更清晰、更易维护的代码。

全局作用域和函数作用域

全局作用域是整个程序可以访问的作用域。全局作用域中的变量可以在程序中的任何位置访问和使用。

函数作用域是函数内部的作用域。函数作用域中的变量只能在函数内部访问和使用。

如果一个变量在全局作用域中声明,那么它可以在程序中的任何位置访问。如果一个变量在函数作用域中声明,那么它只能在该函数内部访问。

例如,以下代码中,变量 x 在全局作用域中声明,因此它可以在程序中的任何位置访问。变量 y 在函数 foo 中声明,因此它只能在函数 foo 内部访问。

var x = 10;

function foo() {
  var y = 20;
}

console.log(x); // 10
console.log(y); // ReferenceError: y is not defined

块级作用域

块级作用域是使用 letconst 关键字声明的变量的作用域。块级作用域中的变量只能在声明它们的块内访问和使用。

块级作用域可以帮助我们编写出更清晰、更易维护的代码。例如,以下代码中,变量 xif 语句块中声明,因此它只能在 if 语句块内访问。变量 yfor 语句块中声明,因此它只能在 for 语句块内访问。

if (true) {
  let x = 10;
}

for (let i = 0; i < 10; i++) {
  const y = 20;
}

console.log(x); // ReferenceError: x is not defined
console.log(y); // ReferenceError: y is not defined

自由变量

自由变量是指在函数内部使用但没有在函数内部声明的变量。自由变量的值是从函数的作用域链中获取的。

自由变量可以导致代码难以理解和维护。例如,以下代码中,函数 foo 使用了自由变量 x。如果我们修改了变量 x 的值,那么函数 foo 的行为也会发生改变。

var x = 10;

function foo() {
  console.log(x);
}

x = 20;

foo(); // 20

什么是作用域链

作用域链是指变量在不同作用域中查找变量值的顺序。作用域链从当前作用域开始,然后向上查找父作用域,依次类推,直到找到变量的定义或到达全局作用域。

作用域链可以帮助我们理解为什么变量在某些情况下可以访问,而在其他情况下却不能访问。例如,如果一个变量在函数作用域中声明,那么它只能在该函数内部访问。但是,如果该变量在全局作用域中声明,那么它可以在程序中的任何位置访问。

例如,以下代码中,变量 x 在全局作用域中声明,因此它可以在程序中的任何位置访问。变量 y 在函数 foo 中声明,因此它只能在函数 foo 内部访问。

var x = 10;

function foo() {
  var y = 20;

  console.log(x); // 10
  console.log(y); // 20
}

foo();

关于自由变量的取值

自由变量的值是从函数的作用域链中获取的。作用域链从当前作用域开始,然后向上查找父作用域,依次类推,直到找到变量的定义或到达全局作用域。

如果一个自由变量在当前作用域中没有定义,那么它将在父作用域中查找。如果在父作用域中也没有找到,那么它将在再上层的作用域中查找,依次类推,直到找到变量的定义或到达全局作用域。

如果一个自由变量在整个作用域链中都没有找到,那么它将被视为未定义。

作用域与执行上下文

执行上下文是指 JavaScript 引擎在执行代码时所处