【问题标题】:When to use const with objects in JavaScript?何时在 JavaScript 中对对象使用 const?
【发布时间】:2017-06-17 11:43:28
【问题描述】:

我最近读到了 ES6 const 关键字,我可以理解它在有这样的东西时的重要性:

(function(){
    const PI = 3.14;
    PI = 3.15; //  Uncaught TypeError: Assignment to constant variable
})();

所以,没有人可以更改我的 PI 变量。

我的误解是我不明白在什么情况下将const 与对象一起使用是有意义的(除了阻止人们使用myObj = newValue;)。

(function(){
    const obj = {a:1 ,b: 2, c:3};
    //obj = {x:7 , y:8, z: 9}
    //This is good
    //TypeError: Assignment to constant variable.

    obj.a=7; obj.b=8 ; obj.c=9;
    console.log(obj); //outputs: {a: 7, b: 8, c: 9}
})();

所以当声明一个对象时:我什么时候应该说:现在我必须const声明我的对象?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    这是网络上的一个常见误解,CONST 不创建不可变变量,而是创建不可变绑定。

    例如。

     const temp1 = 1;
     temp1  = 2 //error thrown here.
    

    但是

     temp1.temp = 3 // no error here. Valid JS code as per ES6
    

    所以const 创建了到那个特定对象的绑定。 const 确保变量 temp1 不会有任何其他对象的 Binding。

    现在来到Object。我们可以使用Object.freeze 来获得Object 的不可变特性

    const temp3 = Object.freeze( {a:3,b:4})
    temp3.a = 2 // it wont update the value of a, it still have 3
    temp3.c = 6 // still valid but wont change the object
    

    【讨论】:

    • 感谢您的明确答复。你能解释一下“const如何确保变量temp1不会有任何其他对象的绑定。”?
    • 任何参考说明?
    • @TechTurtle ,在浏览器的控制台中执行上述示例
    • @TechTurtle 我有点晚了,但只是为了完整起见:Hereconst 的参考,hereObject.freeze() 的参考。
    【解决方案2】:

    根据ES6-Features.org,常量用于制作“不能重新分配新内容的变量”。

    const 关键字使变量本身不可变,而不是其分配的内容。当内容是对象时,这意味着对象本身仍然可以更改。

    因此,可以更改使用const 变量声明的对象的内容,但不能将新对象分配给const 变量。

    您仍然可以向对象添加新属性。

    const myVar = "someValue";
    const myObj = {"name": "nameValue", "age": 14}
    
    console.log(myVar); //someValue
    console.log(myObj.name); //nameValue
    
    myObj.name = "newNameValue"; 
    console.log(myObj.name); //newNameValue
    
    myObj.someNewAttr = "newAttrValue";
    console.log(myObj.someNewAttr); //newAttrValue
    
    myObj = {"newNameAttr": "newNameValue"}; //Uncaught TypeError: Assignment to constant variable.
    console.log(myObj.newNameAttr);
    
    myVar = "newValue"; //Uncaught TypeError: Assignment to constant variable.
    console.log(myVar);

    你也可以在这个小提琴上看到:https://jsfiddle.net/am2cbb00/1/

    【讨论】:

    • 那么......这样的东西会在函数的顶部做什么? const obj = new myObject(this, data); 我不确定它是像 PHP 中的静态还是更像是 ..ehm.. 单例模式,但是使用.. erhm ...“可重复”构造函数?或者也许只是一个程序员无缘无故炫耀他闪亮的新关键字......
    • @ChristofferBubach 它是 javascript 中的构造函数。 “new”关键字用于创建对象的实例。基本上,它创建一个新对象并为其分配一个 const 变量。因此,该 const 变量不能与另一个对象绑定。只能更改和更新对象的内容。另请在此处查看 JS 中“新”关键字的用法:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 我知道我的构造函数是什么——我的问题是:第二次调用函数时会发生什么?对象是用新的数据变量重新初始化,还是更像是调用之间的静态?我发现不清楚为什么要在这样的函数中使用它。
    • @ChristofferBubach 第二次调用该函数时,它会完全初始化“myObject”的一个新实例,但不可能将该新实例分配给同一个“obj”变量,因为它是定义的常量变量。在您的示例中,构造函数所有者还使用“this”传递当前对象范围。开发人员可能希望在构造函数中从该范围内访问某个变量。
    • 所以问题是,如果您要更改/重新分配对象的属性,使用对象是否合适(最佳实践)?
    【解决方案3】:

    let 和 const 用于类型安全。没有您必须使用它们的情况,但它们可以很方便并减少难以发现的错误。

    一个示例,其中 const 对您不想转换为另一种类型的对象很有用。

    const x = {"hello":"world"};
    
    // This is OK
    x.hello = "stackoverflow";
    
    // This is not OK
    x = JSON.stringify(x);
    

    【讨论】:

      【解决方案4】:

      如果您使用对象并希望确保对象的身份永远不会更改,请说:

      const a = {};
      
      a.b = 1;
      
      // ... somewhere in the other part of the code or from an async call
      // suddenly
      
      someAjaxCall().then(() => { a = null; }) // for preventing this
      

      另外,使用const 是 javascript 编译器对代码进行优化的一个很好的提示,从而使执行速度比使用 letvar 快​​得多,因为标识永远不会改变,

      但是

      出于性能原因,请注意在循环中使用 const/let,因为它可能会由于每个循环创建一个变量而降低性能,但在大多数情况下,差异可以忽略不计。

      【讨论】:

        【解决方案5】:

        const 实际上创建了不可变绑定,而不是使变量不可变。

        由于原始数据类型(BooleannullundefinedStringNumber)是按值传递的,它们本身变得不可变,因此不能重新分配给某些其他值。

        对于复杂数据类型(ArrayFunctionObject),它们通过引用传递。当我们更改或修改它们的属性/元素时,我们不会更改它们的绑定,因此const 不会引发任何错误。

        【讨论】:

          【解决方案6】:

          const 使name AND 内容不可变,除非内容是对象,否则只能更改内容。

          
          const n = 1; 
          n = 2; // Uncaught type error
          let n = 2 // Already assigned
          
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-26
            • 2019-03-09
            • 2017-12-30
            • 1970-01-01
            • 2016-06-16
            • 1970-01-01
            相关资源
            最近更新 更多