在JavaScript中,为什么不能修改常量String但可以修改常量数组

时间:2018-08-05 15:59:16

标签: javascript arrays const

const name = 1;
name = 2;

执行此JavaScript时出现错误:

TypeError: Assignment to constant variable.
    at Object.<anonymous> (/home/user01/JavaScript/scope.js:2:6)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3

但是,在执行以下语句时,代码将成功执行。

const arr = [1,2,3];
arr[1] = 5;

为什么即使声明为常量,我们也可以修改数组。

2 个答案:

答案 0 :(得分:5)

由于数组本身未更改,因此它仍然是同一数组。在类似C的语言中,与此类似的将是一个常量指针(指向内存中的某个地址)–您无法更改指针指向的位置,但是内存可以写得一样。

在JavaScript中,这种类似指针的行为适用于所有不是基本元素(即NumberBooleanString ...)的东西,它基本上是数组和对象。如果您想知道String为什么是原始元素,那是因为in JavaScript Strings are immutable

答案 1 :(得分:3)

ES2015 const并不表示值是constantimmutableconst值肯定可以更改。以下是不引发异常的完全有效的ES2015代码:

const obj = {};
obj.bar = 42;
console.log(obj.bar);
// → 42

const arr = [1, 2, 3];
arr[1] = 42;
console.log(arr[1]);
// → 42

这里唯一不变的是绑定。 const为变量名(obj)分配值({})或为变量名(arr)分配([]),并保证不会发生重新绑定。在assignment operator变量上使用unarypostfixconst - ++ 运算符将引发TypeError Exception

因此,以下任何一行都将引发异常。

const foo = 27;
foo = 42;
foo *= 42;
foo /= 42;
foo %= 42;
foo += 42;
foo -= 42;

现在的问题是如何使变量immutable

原始值,即numbersstringsbooleanssymbolsnullundefined始终是不可变的。

var foo = 27;
foo.bar = 42;
console.log(foo.bar);
// → `undefined`

要设置对象的immutable,请使用Object.freeze()。自 ES5 起就出现了,如今已广泛使用。

const foo = Object.freeze({
    'bar': 27
});
foo.bar = 42; // throws a TypeError exception in strict mode;
              // silently fails in sloppy mode
console.log(foo.bar);
// → 2