Axel Rauschmayer博士在探索ES6中有const定义:
const
就像let一样工作,但是您声明的变量必须立即初始化,并且其值以后不能更改。[…]
const bar = 123; bar = 456; // TypeError: `bar` is read-only
然后他写道
const
仅表示变量始终具有相同的值,但并不表示该值本身是不变的。
我对此陷阱感到困惑。有人可以const
用这个陷阱清楚地定义吗?
Axel Rauschmayer博士在探索ES6中有const定义:
const
就像let一样工作,但是您声明的变量必须立即初始化,并且其值以后不能更改。[…]
const bar = 123; bar = 456; // TypeError: `bar` is read-only
然后他写道
const
仅表示变量始终具有相同的值,但并不表示该值本身是不变的。
我对此陷阱感到困惑。有人可以const
用这个陷阱清楚地定义吗?
Answers:
MDN很好地总结了一下:
const声明创建对值的只读引用。这并不意味着它拥有的值是不变的,只是不能重新分配变量标识符。例如,如果内容是对象,则意味着对象本身仍可以更改。
更简洁地说:const创建一个不可变的绑定。
换句话说:const与var一样,为您提供了可变的内存块,您可以在其中存储一些内容。但是,const指示您必须继续引用相同的内存块–您不能将变量重新分配给不同的内存块,因为变量引用是恒定的。
要真正使某些内容在声明后保持不变且不变,您需要使用Object.freeze()
。但是,这很浅,仅适用于键/值对。冻结整个对象需要花费更多的精力。以高效的方式重复执行此操作更具挑战性。如果您确实有需要,建议您检查一下Immutable.js之类的内容
var x
是a struct Object *x
,则aconst x
是a struct Object *const x
。指针不能改变。它指向的东西可以。
当您使用const
JavaScript制作内容时,您无法将变量本身重新分配为引用其他内容。但是,该变量仍可以引用可变对象。
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
它更易于理解,因为您无需更改值,而是为变量分配了新值。
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
首先,定义什么是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
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
必须同时声明和分配。myConstant
,出现以下错误:未捕获的TypeError:分配给常数变量
const
仍然是可变的:用Just声明的变量const
不能被重新分配,它仍然是mutable。可变的意味着分配给const
变量的数据结构(对象,数组,地图等)仍然可以更改(即变异)。突变的例子有:
如果确实希望对象不可变,您将必须使用类似的东西Object.freeze()
。这是一种冻结对象的方法。冻结的对象无法再更改,并且不能添加任何新属性。
const obj = {prop1: 1};
obj.prop1 = 2;
obj.prop2 = 2;
console.log(obj);
// We freeze the object here
Object.freeze(obj);
obj.prop1 = 5;
delete obj.prop2;
// The object was frozen and thus not mutated
console.log(obj);