js作用域链简析

72 阅读2分钟

JavaScript 采用词法作用域(Lexical Scoping),也就是静态作用域,函数的作用域在函数定义的时候就决定了。作用域链是函数的一个重要属性,是由当前执行环境和外部引用环境的一系列变量对象组成,它保证了变量的访问有序性和可预测性。

具体来说,当函数执行时,会先从自己内部的作用域中查找变量,如果找不到,就会从自己所处的上级作用域中查找,直到找到该变量或者抵达全局作用域为止。这个查找变量的过程,就形成了作用域链。

举个例子,我们来看一段代码:

var a = 10;
function foo() {
  var b = 20;
  function bar() {
    var c = 30;
    console.log(a + b + c);
  }
  bar();
}
foo();

在执行 bar() 函数时,首先会在 bar() 的作用域中查找变量 abc,由于 a 不在 bar() 的作用域中,因此会向上查找,直到找到为止。这时候就形成了作用域链:

bar() 的变量对象 -> foo() 的变量对象 -> 全局变量对象

因此,在 bar() 中可以访问到 ab 的值,但不能访问 foo() 中的其他变量。

需要注意的是,当变量的值被修改时,也是按照这个规则来进行的。如果在 bar() 函数中修改变量 a 的值,实际上是修改了 foo() 中的变量 a 的值,因为 bar() 的作用域链上存在 foo() 的变量对象。如果在 bar() 函数中声明一个与 a 同名的变量,实际上是在 bar() 的作用域中声明了一个新的变量,与 foo() 中的变量 a 没有任何关系。

总之,作用域链是 JavaScript 中一个非常重要的概念,深入理解作用域链有助于我们编写更加高效和可维护的代码。