ts var 和 let

254 阅读3分钟

作用域:

  • let 具有块级作用域,只在声明的块或语句内部可见。
  • var 具有函数级作用域,可在整个函数内部访问。

以下是一个示例,展示了 letvar 的作用域区别:

function example() {
  if (true) {
    let x = 10; // 块级作用域内的变量
    var y = 20; // 函数级作用域内的变量
    console.log(x); // 输出 10
    console.log(y); // 输出 20
  }
  console.log(x); // 错误:x 未定义
  console.log(y); // 输出 20
}

example();

在上面的示例中,x 是使用 let 声明的变量,它只在 if 语句块内部可见。而 y 是使用 var 声明的变量,它在整个函数内部都可见。

变量提升:

  • 使用 let 声明的变量不存在变量提升,必须在声明之后才能访问。
  • 使用 var 声明的变量会被提升到其作用域的顶部,可以在声明之前访问。

以下是一个示例,展示了 letvar 的变量提升区别:

function example() {
  console.log(x); // 输出 undefined
  var x = 10;
  console.log(y); // 错误:y 未定义
  let y = 20;
}

example();

在上面的示例中,使用 var 声明的变量 x 在声明之前可以访问,但它的值为 undefined。而使用 let 声明的变量 y 在声明之前是不可访问的。

重复声明:

  • 使用 let 声明的变量不允许在同一作用域内重复声明。
  • 使用 var 声明的变量允许在同一作用域内重复声明,并且后面的声明会覆盖前面的声明。

以下是一个示例,展示了 letvar 的重复声明区别:

function example() {
  let x = 10;
  let x = 20; // 错误:无法重新声明块级作用域的
  var x = 10;
  var x = 20; // 重复声明,覆盖前面的声明
}
example();

闭包

闭包与 var: 使用 var 声明的变量在闭包中具有共享的作用域。这意味着闭包内部的函数可以访问和修改外部函数中声明的变量。

function example() {
  var x = 10;
  function inner() {
    console.log(x); // 10
  }
  inner();
}
example();

在上面的示例中,inner 函数可以访问外部函数 example 中声明的变量 x

闭包与 let: 使用 let 声明的变量在闭包中具有独立的作用域。每次迭代或调用闭包时,都会创建一个新的变量实例。

function example() {
  for (let i = 0; i < 5; i++) {
    setTimeout(function () {
      console.log(i); // 0, 1, 2, 3, 4
    }, 1000);
  }
}
example();

在上面的示例中,setTimeout 函数中的回调函数形成了闭包。使用 let 声明的变量 i 在每次迭代时都会创建一个新的实例,因此每个闭包都能够访问到正确的值。

相比之下,如果我们使用 var 声明变量 i,则所有的闭包都会共享同一个 i,导致输出结果为 5

function example() {
  for (var i = 0; i < 5; i++) {
    setTimeout(function () {
      console.log(i); // 5, 5, 5, 5, 5
    }, 1000);
  }
}
example();

在这个示例中,由于 var 声明的 i 在全局作用域中共享,所有的闭包都使用了相同的 i 值。

通过使用 let 声明变量,我们确保了每个闭包都可以访问到正确的值,而不会受到循环的影响。