【问题标题】:In JavaScript, Why constant String cannot be modified but constant array can be modified在 JavaScript 中,为什么不能修改常量字符串但可以修改常量数组
【发布时间】:2018-08-05 15:59:16
【问题描述】:
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;

为什么我们可以修改一个数组,即使它被声明为常量。

【问题讨论】:

  • 因为const 并不意味着“不可变”,很遗憾。
  • 这是因为 const 不能重新分配。更改数组时不会重新分配变量。如果您不希望 arr 可变,可以使用 Object.freeze(arr)

标签: javascript arrays constants


【解决方案1】:

因为数组本身没有改变,所以还是同一个数组。在类 C 语言中,与此类似的是一个常量指针(指向内存中的某个地址)——您无法更改指针指向的位置,但内存是可写的。

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

【讨论】:

    【解决方案2】:

    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) ,并保证不会发生重新绑定。在const 变量上使用assignment operatorunarypostfix --++ 运算符会引发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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2022-08-02
      • 2020-02-26
      • 1970-01-01
      相关资源
      最近更新 更多