我想知道在ES6中let
和const
有什么区别。它们都是块作用域,如以下代码中的示例所示:
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代码。
你所看到的只是一个实现错误。根据ES6 spec wiki on const
,const
是:
初始化一次,只读其后的绑定形式是有用的,并且在现有实现中以const声明的形式具有先例。
这意味着只读,就像现在一样。在Traceur和Continuum中对const
的ES6实现是错误的(它们可能只是忽略了它)
let
和const
之间的区别在于,一旦使用const
将值/对象绑定到变量,就无法重新分配给该变量。例:
const something = {};
something = 10; // Error.
let somethingElse = {};
somethingElse = 1000; // This is fine.
请注意,const
不会产生不可变的东西。
const myArr = [];
myArr.push(10); // Works fine.
可能目前使对象(浅)不可变的最佳方法是在其上使用Object.freeze()
。
let abc = 0;
if(true)
abc = 5 //fine
if(true){
let def = 5
}
console.log(def)
// Low readability
if (x > 10) {
}
//Better!
const maxRows = 10;
if (x > maxRows) {
}
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
}
let
和const
关键字都是声明块范围变量的方法。但是有一个很大的不同:
let
声明的变量可以重新分配。const
声明的变量必须在声明时初始化,并且不能重新分配。如果您尝试使用const
关键字声明重新分配变量,您将收到以下错误(chrome devtools):
如果我们知道我们想要分配一次变量并且我们不想重新分配变量,那么使用const
关键字可以提供以下优势:
const
声明的变量。这样我们的代码就变得更具说明性并且更易于使用。尽管使用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()
来实现此目的。
让和const
用let
和const
声明的变量消除了特定的悬挂问题,因为它们的范围是块,而不是功能。
如果在代码块内使用let
或const
声明变量(用花括号{}表示),那么变量将被卡在所谓的时间死区中,直到处理变量的声明为止。此行为可防止变量仅在声明之后才被访问。
使用let和const的规则
let
和const
也有一些其他有趣的属性。
let
声明的变量可以重新分配,但不能在同一范围内重新声明。const
声明的变量必须分配初始值,但不能在同一范围内重新声明,并且不能重新分配。用例
最大的问题是你什么时候应该使用let
和const
?一般的经验法则如下:
let
const
。由于const
是声明变量的最严格方式,因此建议您始终使用const
声明变量,因为它会使您的代码更易于推理,因为您知道标识符在程序的整个生命周期内都不会更改。如果您发现需要更新变量或更改变量,请返回并将其从const
切换到let
。
以下是我在这个问题上帮助我的一些笔记。还将const
和let
与var
进行比较。
这是关于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
这是关于let
和const
:
// 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
新的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
关键字将变量声明附加到其包含的任何块的范围内。
宣言令差异
let
和var
之间的另一个区别是声明/初始化顺序。在声明之前访问由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]
使用let
和For
循环:
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
... in
和for
... of
。