简体   繁体   English

Object.freeze()vs const

[英]Object.freeze() vs const

Object.freeze() seems like a transitional convenience method to move towards using const in ES6. Object.freeze()似乎是一种过渡性的方便方法,可以在ES6中使用const

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 const then switch to using const instead? 我应该使用Object.freeze()直到我使用支持const所有浏览器然后切换到使用const代替?

const and Object.freeze are two completely different things. constObject.freeze是两个完全不同的东西。

const applies to bindings ("variables"). const适用于绑定 (“变量”)。 It creates an immutable binding, ie you cannot assign a new value to the binding. 它创建一个不可变的绑定,即您不能为绑定分配新值。

Object.freeze works on values , and more specifically, object values . Object.freeze适用于 ,更具体地说,是对象值 It makes an object immutable, ie you cannot change its properties. 它使对象不可变,即您无法更改其属性。

In ES5 Object.freeze doesn't work on primitives, which would probably be more commonly declared using const than objects. 在ES5中, Object.freeze不适用于基元,它可能通常使用const不是对象来声明。 You can freeze primitives in ES6, but then you also have support for const . 您可以在ES6中冻结基元,但是您也可以支持const

On the other hand const used to declare objects doesn't "freeze" them, you just can't redeclare the whole object, but you can modify its keys freely. 另一方面,用于声明对象的const不会“冻结”它们,你只是无法重新声明整个对象,但你可以自由地修改它的键。 On the other hand you can redeclare frozen objects. 另一方面,您可以重新声明冻结的对象。

Object.freeze is 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
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 const explanation 另外根据mozilla docs const解释

The const declaration creates a read-only reference to a value. const声明创建对值的只读引用。 It does not mean the value it holds is immutable , solely that the variable identifier can not be reassigned. 它并不意味着它拥有的值是不可变的 ,只是不能重新赋值变量标识符。

This examples created according to babeljs ES6 features. 这个例子是根据babeljs ES6的特点创建的。

Summary: 摘要:

const and Object.freeze() serve totally different purposes. constObject.freeze()用于完全不同的目的。

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

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 const keyword, we can't reassign it. 以下代码抛出错误,因为我们尝试重新分配使用const关键字声明的变量foo,我们无法重新分配它。

Example 2: Data structures which are assigned to const can 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 const keyword and assign an object to it. 在这个例子中,我们使用const关键字声明一个变量并为其分配一个对象。 Although we can't reassign to this variable called object, we can mutate the object itself. 虽然我们无法重新分配这个名为object的变量,但我们可以改变对象本身。 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() . 要禁用对象的任何更改,我们需要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 object1 as an argument the function returns the object which is now 'frozen'. 在这个例子中,当我们调用Object.freeze()并将object1作为参数时,该函数返回现在被“冻结”的对象。 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). 此外,当我们尝试添加或删除任何属性时,我们可以看到这没有任何影响(将在严格模式下抛出错误)。

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 eg Arrays, Objects). 因此, Object.freeze()在具有引用属性(例如Arrays,Objects)时不会完全“冻结”该对象。

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 out side 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 reassigning 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 reassigning 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 reassigned. 整个理解是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. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM