返回

鸟瞰 JavaScript 作用域和闭包概念

前端

理解 JavaScript 作用域和闭包的奥秘

作用域决定变量的生命周期,明确变量的作用域是理解 JavaScript 的关键。我们首先会学习函数作用域。

函数作用域和变量的生命周期

在 JavaScript 中,函数内定义的变量只在该函数内可见,这就是函数作用域。例如:

function greet() {
  // 声明变量
  var name = "Ben";
  // 在函数内使用变量
  console.log("Hello, " + name);
}
// 调用函数
greet();

当调用 greet() 函数时,变量 name 的值是 "Ben",但一旦函数执行完毕,变量 name 就消失了。换句话说,变量 name 的生命周期仅限于函数 greet()。

全局变量与局部变量

全局变量是在函数之外定义的变量,可以在任何地方访问。本地变量是在函数内部定义的变量,只能在该函数内访问。例如:

// 全局变量
var globalName = "John";

function greet() {
  // 局部变量
  var localName = "Jane";
  console.log("Hello, " + globalName);
  console.log("Hello, " + localName);
}

// 调用函数
greet();

当调用 greet() 函数时,可以访问全局变量 globalName 和本地变量 localName。但是,在函数外部,只能访问全局变量 globalName。

词法作用域

JavaScript 中的词法作用域是指函数的嵌套作用域,在嵌套函数内部可以访问父函数的作用域。例如:

function outer() {
  // 外部变量
  var outerVar = "Outer";

  function inner() {
    // 内部变量
    var innerVar = "Inner";

    // 访问外部变量
    console.log("Outer: " + outerVar);
    // 访问内部变量
    console.log("Inner: " + innerVar);
  }
  inner();
}
outer();

当调用 outer() 函数时,内部函数 inner() 可以访问 outer() 函数的作用域,从而可以访问 outerVar 变量。这正是词法作用域的体现。

闭包

闭包是指一个函数可以访问另一个函数作用域中的变量。例如:

function outer() {
  // 外部变量
  var outerVar = "Outer";

  // 返回一个内部函数
  return function() {
    // 内部变量
    var innerVar = "Inner";

    // 访问外部变量
    console.log("Outer: " + outerVar);
    // 访问内部变量
    console.log("Inner: " + innerVar);
  };
}
// 存储返回的内部函数
var innerFunc = outer();

// 调用内部函数
innerFunc();

函数 outer() 返回一个内部函数,该内部函数可以访问 outer() 函数的作用域,从而可以访问 outerVar 变量。即使 outer() 函数已经执行完毕,但内部函数 innerFunc() 仍然可以访问 outerVar 变量。这就是闭包。

闭包是 JavaScript 中非常强大的工具,可以在多个用例中派上用场。例如,闭包可以用来创建私有变量,实现模块化编程等。

希望这篇文章能帮助您更好地理解 JavaScript 作用域和闭包概念。