javascript - "let"和 "var"和有什么区别?

标签 javascript scope ecmascript-6 var let

ECMAScript 6 推出 the let statement .

我听说它被描述为局部变量,但我仍然不太确定它的行为与 var 关键字有何不同。

有什么区别?什么时候应该使用 let 代替 var

最佳答案

范围规则

主要区别在于范围规则。由 var 关键字声明的变量的作用域为直接函数体(因此是函数作用域),而 let 变量的作用域为直接封闭 block ,表示为通过 { } (因此是 block 作用域)。

function run() {
  var foo = "Foo";
  let bar = "Bar";

  console.log(foo, bar); // Foo Bar

  {
    var moo = "Mooo"
    let baz = "Bazz";
    console.log(moo, baz); // Mooo Bazz
  }

  console.log(moo); // Mooo
  console.log(baz); // ReferenceError
}

run();

let 关键字引入该语言的原因是函数作用域令人困惑,并且是 JavaScript 中错误的主要来源之一。

看看 another Stack Overflow question 中的这个示例:

var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
  // and store them in funcs
  funcs[i] = function() {
    // each should log its value.
    console.log("My value: " + i);
  };
}
for (var j = 0; j < 3; j++) {
  // and now let's run each one to see
  funcs[j]();
}

My value: 3 每次调用 funcs[j](); 时都会输出到控制台,因为匿名函数绑定(bind)到同一个变量。

人们必须创建立即调用的函数来从循环中捕获正确的值,但这也很麻烦。

吊装

而使用 var 关键字声明的变量为 hoisted (在代码运行之前用 undefined 初始化)这意味着即使在声明它们之前,它们也可以在其封闭范围内访问:

function run() {
  console.log(foo); // undefined
  var foo = "Foo";
  console.log(foo); // Foo
}

run();

let 变量在其定义被评估之前不会被初始化。在初始化之前访问它们会导致 ReferenceError。据说该变量从 block 的开始一直处于“临时死区”,直到处理初始化为止。

function checkHoisting() {
  console.log(foo); // ReferenceError
  let foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();

创建全局对象属性

在顶层,letvar 不同,不会在全局对象上创建属性:

var foo = "Foo";  // globally scoped
let bar = "Bar"; // not allowed to be globally scoped

console.log(window.foo); // Foo
console.log(window.bar); // undefined

重新声明

在严格模式下,var 将允许您在同一范围内重新声明相同的变量,而 let 会引发语法错误。

'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.

let bar = "bar1"; 
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared

关于javascript - "let"和 "var"和有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41870845/

相关文章:

javascript - 将 react-quill 用于博客应用程序,以便用户可以创建帖子。如何在 React 中正确显示一串 html 元素?

javascript - 如何在 angularjs 中将字符串连接到 $scope 模型?

python - 首次使用后重新分配时局部变量出现 UnboundLocalError

java - 监听所有表单提交事件并在任何其他附加事件处理程序之前执行功能

javascript - 如何修复 Bootstrap 覆盖的可访问性

JavaScript 赋予被调用函数访问调用函数变量的权限

ecmascript-6 - 如何排查 es6 模块依赖问题?

javascript - 使用 ES6 扩展运算符 react props 语法

javascript - Angular 的 $http 中返回的 Promise 与普通 Javascript (ES6) 中返回的 Promise 相同吗?

javascript - 如何使 WebSQL 查询同步?