急冻() vs const

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

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

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

72947 次浏览

在 ES5中,Object.freeze不能在原语上工作,与对象相比,使用 const声明原语可能更为常见。您可以在 ES6中冻结原语,但是也支持 const

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

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

上面的示例完全使您的对象不可变。

让我们看下面的例子。

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

不会出错的。

但是如果你这样做

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

它会抛出类似“ obj 是只读的”这样的错误。

另一个用例

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

它会抛出 Duplicate declaration "obj"

同时根据 Mozilla 文件 康斯特的解释

Const 声明创建一个对值的只读引用。 < strong > It 并不意味着它所持有的值是不可变的 ,只是 无法重新分配变量标识符。

这个示例是根据 babeljsES6特性创建的。

constObject.freeze是两个完全不同的东西。

const应用于 束缚(“变量”)。它创建了一个不可变的绑定,也就是说,您不能为绑定赋予一个新值。

Object.freeze适用于 价值观,更确切地说,是 对象值。它使得对象不可变,也就是说,你不能改变它的属性。

摘要:

constObject.freeze()的用途完全不同。

  • const是用来声明一个必须马上赋值且不能重新赋值的变量。const声明的变量是块作用域,而不是像 var声明的变量那样的函数作用域
  • Object.freeze()是一个接受对象并返回相同对象的方法。现在,对象不能删除其任何属性或添加任何新属性。

例子 const:

示例1: 无法重新分配 const

const foo = 5;


foo = 6;

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

例子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

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

例子 Object.freeze():

示例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

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

示例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);

这个示例显示嵌套对象(以及其他引用数据结构)的属性是 还是易变的。因此,当对象具有引用属性(例如数组、对象)时,Object.freeze()不会完全“冻结”对象。

简单点。

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

Const -它是块范围变量,类似于 let,它的值无法重新分配,需要重新声明。

也就是说

{
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

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

返回文章页面 对象根属性是不可更改的,我们也不能添加和删除更多的属性,但我们可以重新分配整个对象。

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

//两者的相似之处在于,嵌套对象是可更改的

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


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

谢谢。