我知道ES6尚未标准化,但JS中的lot of browsers currently support const
关键字。
在规范中,写道:
常量的值不能通过重新赋值来改变,而a 常数不能重新申报。因此,尽管如此 如果没有初始化就可以声明一个常量,那就是 无用的。
当我做这样的事情时:
const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];
我发现一切正常xxx
仍为6
且yyy
为[]
。
但如果我yyy.push(6); yyy.push(1);
,我的常数数组已被更改。现在它是[6, 1]
,顺便说一下,我仍然无法用yyy = 1;
更改它。
我这是一个错误,还是我错过了什么?我试用了最新的chrome和FF29
答案 0 :(得分:106)
文档说明:
...常数不能通过重新分配来改变 ...常数不能重新声明
当您添加到数组或对象时,您没有重新分配或重新声明常量,它已经被声明和分配,您只需添加常量指向的“列表”。 / p>
所以这很好用
const x = {};
x.foo = 'bar';
console.log(x); // {foo : 'bar'}
和这个
const y = [];
y.push('foo');
console.log(y); // ['foo'];
但不是这些
const x = {};
x = {foo: 'bar'}; // error - re-assigning
const y = ['foo'];
const y = ['bar']; // error - re-declaring
const foo = 'bar';
foo = 'bar2'; // error - can not re-assign
var foo = 'bar3'; // error - already declared
function foo() {}; // error - already declared
答案 1 :(得分:24)
这是因为您的常量实际上是将引用存储到数组中。当您将某些内容加入到数组中时,您不会修改常量值,而是指向它所指向的数组。如果将对象分配给常量并尝试修改它的任何属性,也会发生同样的情况。
如果要冻结数组或对象以使其无法修改,可以使用Object.freeze
方法,该方法已经是ECMAScript 5的一部分。
const x = Object.freeze(['a'])
x.push('b')
console.log(x) // ["a"]
答案 2 :(得分:5)
这是我能想到的每种编程语言的一致行为。
考虑C - 数组只是美化指针。常量数组只表示指针的值不会改变 - 但实际上该地址包含的数据是免费的。
在javascript中,你可以调用常量对象的方法(当然 - 否则常量对象不会起到太多作用!)这些方法可能会产生修改对象的副作用。由于javascript中的数组是对象,因此这种行为也适用于它们。
你可以确定的是,常量总是指向同一个对象。对象本身的属性可以自由更改。
答案 3 :(得分:2)
const声明创建对值的只读引用。它并不意味着它拥有的值是不可变的,只是不能重新赋值变量标识符。例如,在内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。
此外,还有一个重要的注意事项:
全局常量不会成为窗口对象的属性...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
答案 4 :(得分:0)
我认为这将使您在以下问题上更加清楚:https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0。
基本上,它归结为const
,始终指向内存中的同一地址。您可以更改存储在该地址中的值,但也不能更改const
指向的地址。
当const
指向具有原始值的地址时,您提到的const
的定义将成立。这是因为您不能在不更改其地址的情况下为该const
分配值(因为这是分配原始值的工作方式),并且不允许更改const
的地址。
好像const
指向非原始值一样,可以编辑地址的值。
答案 5 :(得分:0)
在搜索为什么即使将对象定义为const
后仍然能够更新对象时,请仔细阅读本文。因此,这里的要点是,它不是直接的Object而是它包含的可以更新的属性。
例如,我的对象看起来像:
const number = {
id:5,
name:'Bob'
};
以上答案正确指出,是const对象而不是其属性。因此,我将可以通过以下操作来更新ID或名称:
number.name = 'John';
但是,我将无法像这样更新对象本身:
number = {
id:5,
name:'John'
};
TypeError: Assignment to constant variable.
答案 6 :(得分:0)
因为您可以在const中更改对象的值,所以该对象实际上并不存储分配数据,而是指向它。 因此Javascript中的原语和对象之间是有区别的。
答案 7 :(得分:0)
const 变量存放的是常量的地址(内存地址如 0xFF2DFC)。
常量不是内存中的内容。
常量只是内存地址
感谢您的阅读。
答案 8 :(得分:0)
const
不会阻止诸如 arrays
、objects
之类的复杂对象被修改。它只是防止重新分配或完全覆盖
示例:
In case of variable:
const xxx = 6;
xxx = 999; // error
这里不接受重新分配 const 变量。
In case of object:
const person = {
first_name: "John",
};
// reassigning the object
person = {
first_name: "Michal", // error
};
// redeclear the object
const person = {
first_name: "Michal", // error
};
// But:
person.last_name = "Doe"; // correct
Output:
console.log(person);
// Output => { first_name: "John", last_name: "Doe" }
In case of an array:
const days = ["Sunday"];
// reassigning array
days = ["Monday"]; // error
// redeclear array
const days = ["Monday"]; // error
// But
days.push("Monday"); // correct
Output:
console.log(days);
// output => [ "Sunday", "Monday" ]
答案 9 :(得分:0)
const MY_OBJECT = {'key': 'value'};
// 试图覆盖对象抛出错误
// 未捕获的类型错误:赋值给常量变量。
MY_OBJECT = {'OTHER_KEY': 'value'};
// 但是,对象键不受保护,
// 所以下面的语句执行没有问题
MY_OBJECT.key = 'otherValue';
// 使用 Object.freeze() 使对象不可变
// 同样适用于数组
const MY_ARRAY = [];
// 可以将项目推入数组
MY_ARRAY.push('A');
// ["A"]
// 但是,将新数组分配给变量会引发错误
// 未捕获的类型错误:赋值给常量变量。
MY_ARRAY = ['B'];
答案 10 :(得分:0)
关键字 const 有点误导。
它没有定义一个常数值。它定义了一个对值的常量引用。
因此你不能:
但你可以: