'let'和'const'ECMAScript 2015(ES6)有什么区别?

问题描述 投票:44回答:7

我想知道在ES6中letconst有什么区别。它们都是块作用域,如以下代码中的示例所示:

const PI = 3.14;
console.log(PI);

PI = 3;
console.log(PI);

const PI = 4;
console.log(PI);

var PI = 5;
console.log(PI);

在ES5中,输出将是:

3.14
3.14
3.14
3.14

但在ES6中它将是:

3.14
3
4
5

我想知道为什么ES6允许更改const值,问题是为什么我们现在应该使用'const'?我们可以使用'let'代替吗?

注意:jsbin可用于测试,选择JavaScript运行ES5代码,Traceur运行ES6代码。

javascript ecmascript-5 ecmascript-6
7个回答
23
投票

你所看到的只是一个实现错误。根据ES6 spec wiki on constconst是:

初始化一次,只读其后的绑定形式是有用的,并且在现有实现中以const声明的形式具有先例。

这意味着只读,就像现在一样。在Traceur和Continuum中对const的ES6实现是错误的(它们可能只是忽略了它)

这是一个Github issue regarding Traceur not implementing const


55
投票

letconst之间的区别在于,一旦使用const将值/对象绑定到变​​量,就无法重新分配给该变量。例:

const something = {};
something = 10; // Error.

let somethingElse = {};
somethingElse = 1000; // This is fine.

请注意,const不会产生不可变的东西。

const myArr = [];
myArr.push(10); // Works fine.

可能目前使对象(浅)不可变的最佳方法是在其上使用Object.freeze()


6
投票

let

  • 在编程中使用块范围。
  • 对于每个块,让我们创建自己的新范围,您无法在该块之外访问它。
  • 值可以根据需要多次更改。
  • let对绝大多数代码都非常有用。它可以极大地增强您的代码可读性并减少编程错误的可能性。 let abc = 0; if(true) abc = 5 //fine if(true){ let def = 5 } console.log(def)

const

  • 它允许您使用变量不可变。
  • const是可读性和可维护性的良好实践,并且避免使用魔术文字,例如 // Low readability if (x > 10) { } //Better! const maxRows = 10; if (x > maxRows) { }
  • const声明必须初始化 const foo; // ERROR: const declarations must be initialized
  • const就像我们在let:+中看到的一样
const foo = 123;
if (true) {
    const foo = 456; // Allowed as its a new variable limited to this `if` block
}

3
投票

摘要:

letconst关键字都是声明块范围变量的方法。但是有一个很大的不同:

  • 使用let声明的变量可以重新分配。
  • 使用const声明的变量必须在声明时初始化,并且不能重新分配。

如果您尝试使用const关键字声明重新分配变量,您将收到以下错误(chrome devtools):

const reassignment error

我们为什么要用它?

如果我们知道我们想要分配一次变量并且我们不想重新分配变量,那么使用const关键字可以提供以下优势:

  • 我们在代码中告知我们不想重新分配变量。这样,如果其他程序员查看您的代码(或者甚至是您之前编写的自己的代码),您就会知道不应该重新分配使用const声明的变量。这样我们的代码就变得更具说明性并且更易于使用。
  • 我们强制不能重新分配变量的原则(JS引擎抛出错误)。这样,如果您不小心尝试重新分配一个不打算重新分配的变量,您可以在较早阶段检测到这一点(因为它已记录到控制台)。

警告:

尽管使用const声明的变量无法重新分配,但这并不意味着分配的对象不可变。例如:

const obj = {prop1: 1}

// we can still mutate the object assigned to the 
// variable declared with the const keyword
obj.prop1 = 10;
obj.prop2 = 2;

console.log(obj);

如果您还希望您的对象不可变,您可以使用Object.freeze()来实现此目的。


1
投票

让和const

letconst声明的变量消除了特定的悬挂问题,因为它们的范围是块,而不是功能。

如果在代码块内使用letconst声明变量(用花括号{}表示),那么变量将被卡在所谓的时间死区中,直到处理变量的声明为止。此行为可防止变量仅在声明之后才被访问。

使用let和const的规则

letconst也有一些其他有趣的属性。

  • 使用let声明的变量可以重新分配,但不能在同一范围内重新声明。
  • 使用const声明的变量必须分配初始值,但不能在同一范围内重新声明,并且不能重新分配。

用例

最大的问题是你什么时候应该使用letconst?一般的经验法则如下:

  • 计划将新值重新分配给变量时使用let
  • 如果不打算将新值重新分配给变量,请使用const

由于const是声明变量的最严格方式,因此建议您始终使用const声明变量,因为它会使您的代码更易于推理,因为您知道标识符在程序的整个生命周期内都不会更改。如果您发现需要更新变量或更改变量,请返回并将其从const切换到let


0
投票

以下是我在这个问题上帮助我的一些笔记。还将constletvar进行比较。

这是关于var

// Var
// 1. var is hoisted to the top of the function, regardless of block
// 2. var can be defined as last line and will be hoisted to top of code block
// 3. for undefined var //output error is 'undefined' and code continues executing
// 4. trying to execute function with undefined variable
// Example: // log(myName); // output: ReferenceError: myName is not defined and code stops executing 

这是关于letconst

// Let and Const
// 1. use `const` to declare variables which won't change
// 2. `const` is used to initialize-once, read-only thereafter
// 3. use `let` to declare variables which will change
// 4. `let` or `const` are scoped to the "block", not the function
// 5. trying to change value of const and then console.logging result will give error
// const ANSWER = 42;
// ANSWER = 3.14159;
// console.log(ANSWER);
// Error statement will be "TypeError: Assignment to constant variable." and code will stop executing
// 6. `let` won't allow reference before definition
// function letTest2 () {
//   log(b);
//   let b = 3;}
// Error statement will be "ReferenceError: b is not defined." and code will stop executing

0
投票

ES6 let and const

新的let允许您声明一个范围受限于块的变量(局部变量)。主要区别在于var变量的范围是整个封闭函数:

if (true) {
  var foo = 42; // scope globally
}

console.log(foo); // 42

在范围中使用let

if (true) {
  let foo = 42; // scoped in block
}

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

在函数范围中使用var与使用let相同:

function bar() {
  var foo = 42; // scoped in function
}

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

let关键字将变量声明附加到其包含的任何块的范围内。

宣言令差异

letvar之间的另一个区别是声明/初始化顺序。在声明之前访问由let声明的变量会导致ReferenceError。

console.log(a); // undefined
console.log(b); // ReferenceError: b is not defined

var a = 1;
let b = 2;

使用const

另一方面,使用ES6 const就像使用let一样,但是一旦赋值,它就无法改变。使用const作为不可变值来防止变量被意外重新分配:

const num = 42;

try {
  num = 99;
} catch(err) {
  console.log(err);
  // TypeError: invalid assignment to const `number'

}

num; // 42

使用const分配在现实生活中恒定的变量(例如冷冻温度)。 JavaScript const不是要创建不可更改的值,它与值无关,const是为了防止为变量重新分配另一个值并使变量为只读。但是,值可以随时更改:

const arr = [0, 1, 2];
arr[3] = 3; // [0, 1, 2, 3]

要防止值发生变化,请使用Object.freeze()

let arr = Object.freeze([0, 1, 2]);
arr[0] = 5;

arr; // [0, 1, 2]

使用letFor循环:

let真正有用的特殊情况是在for循环的标题中:

for (let i = 0; i <= 5; i++) {
  console.log(i);
}

// 0 1 2 3 4 5

console.log(i); // ReferenceError, great! i is not global

这也适用于其他循环,如for ... infor ... of

© www.soinside.com 2019 - 2024. All rights reserved.