js的作用域有哪些?

56 阅读3分钟

JavaScript 的作用域

JavaScript 中的作用域指的是变量的可访问范围。作用域主要分为以下几种类型:

1. 全局作用域

全局作用域是指在任何地方都可以访问的变量和函数。全局作用域的变量可以通过 window 对象访问(在浏览器环境中)。在全局作用域中定义的变量可以在任何函数内访问。

var globalVar = "I'm a global variable";

function globalFunction() {
  console.log(globalVar); // 输出: I'm a global variable
}

globalFunction();

2. 函数作用域

函数作用域是指在函数内部定义的变量只能在该函数内部访问。使用 var 关键字声明的变量具有函数作用域,意味着它们在函数外部无法访问。

function functionScope() {
  var localVar = "I'm a local variable";
  console.log(localVar); // 输出: I'm a local variable
}

functionScope();
console.log(localVar); // ReferenceError: localVar is not defined

3. 块级作用域

块级作用域是指在 {} 代码块内定义的变量只能在该代码块内访问。ES6 引入了 letconst 关键字,允许我们创建块级作用域的变量。

{
  let blockVar = "I'm a block variable";
  console.log(blockVar); // 输出: I'm a block variable
}

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

4. 词法作用域

JavaScript 使用词法作用域来决定变量的访问权限。这意味着函数的作用域在定义时就已经确定,而不是在执行时。一个函数可以访问其外部作用域中的变量。

function outerFunction() {
  var outerVar = "I'm from outer scope";

  function innerFunction() {
    console.log(outerVar); // 输出: I'm from outer scope
  }

  innerFunction();
}

outerFunction();

5. 作用域链

当我们访问一个变量时,JavaScript 引擎会按照作用域链的顺序进行查找。首先查找当前作用域,如果没有找到,则向上级作用域查找,直到全局作用域为止。

var outerVar = "I'm from outer scope";

function outerFunction() {
  var innerVar = "I'm from inner scope";

  function innerFunction() {
    console.log(innerVar); // 输出: I'm from inner scope
    console.log(outerVar); // 输出: I'm from outer scope
  }

  innerFunction();
}

outerFunction();

6. 立即执行函数表达式 (IIFE)

立即执行函数表达式(IIFE)是一种在定义后立即执行的函数。它创建了一个新的作用域,常用于避免全局变量污染。

(function() {
  var iifeVar = "I'm from IIFE";
  console.log(iifeVar); // 输出: I'm from IIFE
})();

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

7. 闭包

闭包是指一个函数可以记住并访问其外部作用域的变量,即使该函数在其外部作用域之外执行。闭包通常用于实现数据私有性和函数工厂模式。

function makeCounter() {
  let count = 0; // count 是一个私有变量
  return function() {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 输出: 1
console.log(counter()); // 输出: 2

总结

JavaScript 的作用域主要包括全局作用域、函数作用域、块级作用域和词法作用域。通过理解这些作用域的特性,可以有效管理变量的生命周期和可访问性,从而编写出更清晰、可维护的代码。使用 IIFE 和闭包等技术,可以帮助我们更好地控制作用域,保护变量的私有性。