Axel Rauschmayer博士在探索ES6 中有const definition:
const
就像let一样,但你声明的变量必须是 立即初始化,具有无法更改的值 之后即可。 [...]const bar = 123; bar = 456; // TypeError: `bar` is read-only
然后他写了
Pitfall: const does not make the value immutable
const
仅表示变量始终具有相同的值, 但这并不意味着价值本身就是不可变的。
我对这个陷阱感到困惑。任何人都可以清楚地定义const
这个陷阱吗?
答案 0 :(得分:149)
当您在JavaScript中创建const
内容时,您无法重新分配变量本身以引用其他内容。但是,变量仍然可以引用可变对象。
const x = {a: 123};
// This is not allowed. This would reassign `x` itself to refer to a
// different object.
x = {b: 456};
// This, however, is allowed. This would mutate the object `x` refers to,
// but `x` itself hasn't been reassigned to refer to something else.
x.a = 456;
对于字符串和数字等基元,const
更容易理解,因为您不会改变值,而是为变量赋值。
答案 1 :(得分:96)
MDN总结得很好:
const声明创建对值的只读引用。它并不意味着它拥有的值是不可变的,只是不能重新赋值变量标识符。例如,如果内容是一个对象,这意味着对象本身仍然可以被更改。
更简洁:const创建了一个不可变的绑定。
换句话说:const,就像var一样,为你提供了一个可变的内存块,你可以在其中存储一些东西。但是,const指示你必须继续引用同一块内存 - 你不能将变量重新分配给不同的内存块,因为变量引用是常量。
要在声明之后真正使某些东西保持不变且不变,你需要使用像Object.freeze()
这样的东西。但是,这很浅,仅适用于键/值对。冻结整个对象需要更多的努力。以高效的方式反复这样做更具挑战性。如果您确实需要,我建议您查看Immutable.js
答案 2 :(得分:14)
const
和let
声明控制是否允许标识符和值之间的重新绑定(也称为重新分配):
const x = "initial value";
let y = "initial value";
// rebinding/reassignment
try { x = "reassignment" } catch(e) { console.log(x) } // fails
y = "reassignment"; // succeeds
console.log(y);
不变性在类型级别受到控制。 Object
是一个可变类型,而String
是一个不可变类型:
const o = {mutable: true};
const x = "immutable";
// mutations
o.foo = true; // succeeds
x[0] = "I"; // fails
console.log(o); // {mutable: true, foo: true}
console.log(x); // immutable
答案 3 :(得分:1)
首先,在js中定义什么是值。值可以是:布尔值,字符串,数字,对象,函数和未定义的值。
喜欢:人们用你的名字打电话给你,它没有改变。但是,你换衣服。人与你之间的绑定是你的名字。其余的可以改变。很抱歉这个奇怪的例子。
那么,让我举几个例子:
// boolean
const isItOn = true;
isItOn = false; // error
// number
const counter = 0;
counter++; // error
// string
const name = 'edison';
name = 'tesla'; // error
// objects
const fullname = {
name: 'albert',
lastname: 'einstein'
};
fullname = { // error
name: 'werner',
lastname: 'heisenberg'
};
// NOW LOOK AT THIS:
//
// works because, you didn't change the "value" of fullname
// you changed the value inside of it!
fullname.name = 'hermann';
const increase = aNumber => ++aNumber;
increase = aNumber => aNumber + 1; // error
// NOW LOOK AT THIS:
//
// no error because now you're not changing the value
// which is the decrease function itself. function is a
// value too.
let anotherNumber = 3;
const decrease = () => --anotherNumber;
anotherNumber = 10; // no error
decrease(); // outputs 9
const chaos = undefined;
chaos = 'let there be light' // error
const weird = NaN;
weird = 0 // error
正如您所看到的,除非您未将"第一个" 指定的值更改为const,否则不会出现错误。每当您尝试将第一个指定值更改为其他值时,它就会生气,并且会出错。
因此,这是您在使用const
时可能知道的第二件事。也就是说,应该将其初始化为声明中的值,否则它会生气。
const orphan; // error
const rich = 0; // no error
答案 4 :(得分:0)
ES6
/ ES2015
const
关键字: const
关键字用于声明块作用域变量(如使用let
声明)。用const
和let
声明变量之间的区别如下:
const
的变量不能重新分配。const
声明的变量,这就是为什么在声明该变量时必须将其精确赋值一次。
const
在上面的示例中,我们可以观察到以下内容:
// we declare variable myVariable
let myVariable;
// first assignment
myVariable = 'First assingment';
// additional assignment
myVariable = 'Second assignment';
// we have to declare AND initialize the variable at the same time
const myConstant = 3.14;
// This will throw an error
myConstant = 12;
声明的变量myVariable
可以先声明然后再赋值。let
声明的变量myConstant
必须同时声明和分配。const
时,出现以下错误:未捕获的TypeError:分配给常数变量
myConstant
的变量仍然是可变的:用const
声明的变量无法重新分配,它仍然是可变的。可变是指分配给const
变量的数据结构(对象,数组,地图等)仍可以更改(即变异)。突变的例子有:
如果真的希望对象不可变,则必须使用const
之类的东西。这是一种冻结对象的方法。冻结的对象不能再更改,也不能添加新属性。
Object.freeze()