Javascript Object.freeze() 与 const

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33124058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:39:50  来源:igfitidea点击:

Object.freeze() vs const

javascriptecmascript-6

提问by Sergei Basharov

Object.freeze()seems like a transitional convenience method to move towards using constin ES6.

Object.freeze()似乎是const在 ES6 中使用的过渡便利方法。

Are there cases where both take their place in the code or is there a preferred way to work with immutable data?

是否存在两者都在代码中占据一席之地的情况,或者是否有处理不可变数据的首选方式?

Should I use Object.freeze()until the moment all browsers I work with support constthen switch to using constinstead?

我是否应该一直使用Object.freeze()到支持我使用的所有浏览器,const然后改用使用const

回答by Felix Kling

constand Object.freezeare two completely different things.

const并且Object.freeze是完全不同的两件事。

constapplies to bindings("variables"). It creates an immutable binding, i.e. you cannot assign a new value to the binding.

const适用于绑定(“变量”)。它创建了一个不可变的绑定,即您不能为该绑定分配一个新值。

Object.freezeworks on values, and more specifically, object values. It makes an object immutable, i.e. you cannot change its properties.

Object.freeze适用于values,更具体地说,适用于object values。它使对象不可变,即您不能更改其属性。

回答by pawel

In ES5 Object.freezedoesn't work on primitives, which would probably be more commonly declared using constthan objects. You can freeze primitives in ES6, but then you also have support for const.

在 ES5Object.freeze中不适用于原语,原语可能const比对象更常被声明为 using 。你可以在 ES6 中冻结原语,但是你也支持const.

On the other hand constused to declare objects doesn't "freeze" them, you just can't redeclare the whole object, but you can modify its keys freely. On the other hand you can redeclare frozen objects.

另一方面,const用于声明对象不会“冻结”它们,您只是不能重新声明整个对象,但您可以自由修改其键。另一方面,您可以重新声明冻结的对象。

Object.freezeis also shallow, so you'd need to recursively apply it on nested objects to protect them.

Object.freeze也很浅,因此您需要递归地将其应用于嵌套对象以保护它们。

var ob1 = {
   foo : 1,
    bar : {
        value : 2   
    }
};
Object.freeze( ob1 );

const ob2 = {
   foo : 1,
    bar : {
        value : 2   
    }
}

ob1.foo = 4;  // (frozen) ob1.foo not modified
ob2.foo = 4;  // (const) ob2.foo modified

ob1.bar.value = 4;  // (frozen) modified, because ob1.bar is nested
ob2.bar.value = 4;  // (const) modified

ob1.bar = 4;  // (frozen) not modified, bar is a key of obj1
ob2.bar = 4;  // (const) modified

ob1 = {};  // (frozen) ob1 redeclared
ob2 = {}; // (const) ob2 not redeclared

回答by ?lker Korkut

var obj = {
  a: 1,
  b: 2
};
Object.freeze(obj);
obj.newField = 3; // You can't assign new field , or change current fields

The above example it completely makes your object immutable.

上面的例子完全让你的对象不可变。

Lets look following example.

让我们看看下面的例子。

const obj = {
  a: 1,
  b: 2
};
obj.a = 13; // You can change a field
obj.newField = 3; // You can assign new field.

It won't give any error.

它不会给出任何错误。

But If you try like that

但是如果你这样尝试

const obj = {
      a: 1,
      b: 2
    };
obj = {
 t:4
};

It will throw an error like that "obj is read-only".

它会抛出“obj 是只读的”之类的错误。

Another use case

另一个用例

const obj = {a:1};
var obj = 3;

It will throw Duplicate declaration "obj"

它会抛出 Duplicate declaration "obj"

Also according to mozilla docs constexplanation

同样根据 mozilla docs const解释

The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, solely that the variable identifier can not be reassigned.

const 声明创建一个对值的只读引用。这并不意味着它持有的值是不可变的,只是变量标识符不能重新分配。

This examples created according to babeljs ES6 features.

这个例子是根据 babeljs ES6 特性创建的。

回答by Willem van der Veen

Summary:

概括:

constand Object.freeze()serve totally different purposes.

constObject.freeze()服务于完全不同的目的。

  • constis there for declaring a variable which has to assinged right away and can't be reassigned. variables declared by constare block scoped and not function scoped like variables declared with var
  • Object.freeze()is a method which accepts an object and returns the same object. Now the object cannot have any of its properties removed or any new properties added.
  • const是否用于声明必须立即分配且无法重新分配的变量。声明的变量const是块范围的,而不是函数范围的,就像用声明的变量一样var
  • Object.freeze()是一种接受对象并返回相同对象的方法。现在该对象不能删除其任何属性或添加任何新属性。

Examples const:

例子const

Example 1: Can't reassign const

示例 1:无法重新分配 const

const foo = 5;

foo = 6;

The following code throws an error because we are trying to reassign the variable foo who was declared with the constkeyword, we can't reassign it.

以下代码抛出错误,因为我们试图重新分配使用const关键字声明的变量 foo ,我们无法重新分配它。

Example 2: Data structures which are assigned to constcan be mutated

示例 2:分配给的数据结构const可以改变

const object = {
  prop1: 1,
  prop2: 2 
}

object.prop1 = 5;   // object is still mutable!
object.prop3 = 3;   // object is still mutable!

console.log(object);  // object is mutated

In this example we declare a variable using the constkeyword and assign an object to it. Although we can't reassign to this variable called object, we can mutate the object itself. If we change existing properties or add new properties this will this have effect. To disable any changes to the object we need Object.freeze().

在这个例子中,我们使用const关键字声明一个变量并为其分配一个对象。虽然我们不能重新分配给这个名为 object 的变量,但我们可以改变对象本身。如果我们更改现有属性或添加新属性,这将产生影响。要禁用对我们需要的对象的任何更改Object.freeze()

Examples Object.freeze():

例子Object.freeze()

Example 1: Can't mutate a frozen object

示例 1:无法改变冻结对象

object1 = {
  prop1: 1,
  prop2: 2
}

object2 = Object.freeze(object1);

console.log(object1 === object2); // both objects are refer to the same instance

object2.prop3 = 3; // no new property can be added, won't work

delete object2.prop1; // no property can be deleted, won't work

console.log(object2); // object unchanged

In this example when we call Object.freeze()and give object1as an argument the function returns the object which is now 'frozen'. If we compare the reference of the new object to the old object using the ===operator we can observe that they refer to the same object. Also when we try to add or remove any properties we can see that this does not have any effect (will throw error in strict mode).

在这个例子中,当我们调用Object.freeze()object1作为参数给出时,函数返回现在“冻结”的对象。如果我们使用===运算符将新对象的引用与旧对象的引用进行比较,我们可以观察到它们引用的是同一个对象。此外,当我们尝试添加或删除任何属性时,我们可以看到这没有任何效果(在严格模式下会抛出错误)。

Example 2: Objects with references aren't fully frozen

示例 2:具有引用的对象未完全冻结

const object = {
  prop1: 1,
  nestedObj: {
    nestedProp1: 1,
    nestedProp2: 2,
  } 
}


const frozen = Object.freeze(object);

frozen.prop1 = 5; // won't have any effect
frozen.nestedObj.nestedProp1 = 5; //will update because the nestedObject isn't frozen

console.log(frozen);

This example shows that the properties of nested objects (and other by reference data structures) are still mutable. So Object.freeze()doesn't fully 'freeze' the object when it has properties which are references (to e.g. Arrays, Objects).

这个例子表明嵌套对象(和其他引用数据结构)的属性仍然是可变的。因此Object.freeze(),当对象具有引用的属性(例如数组、对象)时,不会完全“冻结”对象。

回答by Himanshu sharma

Let be simple.

简单点吧。

They are different. Check the comments on the code, that will explain each case.

它们是不同的。检查代码上的注释,这将解释每种情况。

Const- It is block scope variable like let, which value can not reassignment, re-declared .

Const- 它是块作用域变量,如let,其值不能重新分配,重新声明。

That means

这意味着

{
 const val = 10;  // you can not access it outside this block, block scope variable

}

console.log(val); // undefined because it is block scope 

const constvalue = 1;
constvalue = 2; // will give error as we are re-assigning the value;
const obj = { a:1 , b:2};

obj.a = 3;
obj.c = 4;
console.log(obj); // obj = {a:3,b:2,c:4} we are not assigning the value of identifier we can 
                  // change the object properties, const applied only on value, not with properties
obj = {x:1};     // error you are re-assigning the value of constant obj 
obj.a = 2 ;     // you can add, delete element of object

The whole understanding is that const is block scope and its value is not re-assigned.

整个理解是 const 是块作用域,它的值不会重新分配。

Object.freeze:The object root properties are unchangeable, also we can not add and delete more properties but we can reassign the whole object again.

Object.freeze:对象根属性是不可更改的,我们也不能添加和删除更多的属性,但我们可以重新分配整个对象。

var x = Object.freeze({data:1,
    name:{
    firstname:"hero", lastname:"nolast"
    }
});

x.data = 12;  // the object properties can not be change but in const you can do
x.firstname ="adasd"; // you can not add new properties to object but in const you can do

x.name.firstname = "dashdjkha"; // The nested value are changeable 

//The thing you can do in Object.freeze but not in const

x = { a: 1};  // you can reassign the object when it is Object.freeze but const its not allowed

// One thing that is similar in both is, nested object are changeable

// 两者相似的一件事是,嵌套对象是可变的

const obj1 = {nested :{a:10}};
var obj2 =  Object.freeze({nested :{a:10}});

obj1.nested.a = 20; // both statement works
obj2.nested.a = 20;

Thanks.

谢谢。