◆

JavaScript 作用域嵌套与作用域链详解

2023-02-02 01:370

什么是作用域嵌套

当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。

示例

如下代码,对 b 进行的 RHS 引用无法在函数 foo 内部完成,但可以在上一级作用域(在这个例子中就 是全局作用域)中完成。

function foo(a) {
  console.log(a + b);
}

var b = 2;
foo(2);

函数被调用之前作用域链已经存在

fxAge = 'fx is 18 years old';

function fxFn() {
  console.log(fxAge); // undefined
  var fxAge = 'fx is 8 years old';
  var fxSub = 'fx is 25 years old';
  console.log(fxAge); // fx is 8 years old
  function fxFnSub() {
    console.log(fxSub); // fx is 25 years old
    console.log(fxAge); // fx is 8 years old
  }

  return fxFnSub;
}

var fx = fxFn();
fx();

如下代码,在函数被执行之前已经创建了两条作用域链:

  • 全局作用域 -> fxFn 函数作用域
  • 全局作用域 -> fxFnSub 函数作用域
var fx = 'fx is a great girl';

function fxFn() {
  // 输出的是全局作用域的 fx:fx is a great girl
  console.log(fx);
}

function fxFnSub() {
  var fx = 'fx is 18 years old';
  return fxFn;
}

var myFx = fxFnSub();
myFx();
// x 的作用域是全局作用域,全局作用域中没有对 a 进行定义
var x = function () {
  console.log(a);
};

function y(f) {
  var a = 2;
  f();
}

y(x); // ReferenceError: a is not defined

综上示例,可以理解为

函数的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。

遍历嵌套作用域链规则

引擎从当前的执行作用域开始查找变量,如果找不到, 就向上一级继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都会停止。

作用域链

如图所示,这个建筑代表程序中的嵌套作用域链。第一层楼代表当前的执行作用域,也就是你所处的位置。建筑的顶层代表全局作用域。

javaScript作用域嵌套

LHS 和 RHS 引用都会在当前楼层进行查找,如果没有找到,就会坐电梯前往上一层楼,如果还是没有找到就继续向上,以此类推。一旦抵达顶层(全局作用域),可能找到了你所需的变量,也可能没找到,但无论如何查找过程都将停止。

变量没有找到的异常情况

LHS 与 RHS 的差异以及出现异常的情况

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEJavaScript 作用域嵌套与作用域链详解加载中