[英]Object.freeze() vs const
Object.freeze()
似乎是一種過渡性的方便方法,可以在ES6中使用const
。
是否有兩種情況都在代碼中占據一席之地,或者是否有一種使用不可變數據的首選方法?
我應該使用Object.freeze()
直到我使用支持const
所有瀏覽器然后切換到使用const
代替?
const
和Object.freeze
是兩個完全不同的東西。
const
適用於綁定 (“變量”)。 它創建一個不可變的綁定,即您不能為綁定分配新值。
Object.freeze
適用於值 ,更具體地說,是對象值 。 它使對象不可變,即您無法更改其屬性。
在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 docs const解釋
const聲明創建對值的只讀引用。 它並不意味着它擁有的值是不可變的 ,只是不能重新賦值變量標識符。
這個例子是根據babeljs ES6的特點創建的。
const
和Object.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()
在具有引用屬性(例如Arrays,Objects)時不會完全“凍結”該對象。
讓我們簡單吧。
它們是不同的 。 檢查代碼的注釋,這將解釋每個案例。
Const - 它是塊范圍變量,就像let一樣,哪個值不能重新賦值,重新聲明。
這意味着
{
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
整個理解是const是塊范圍,它的值不會被重新分配。
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
//兩者相似的一點是,嵌套對象是可變的
const obj1 = {nested :{a:10}};
var obj2 = Object.freeze({nested :{a:10}});
obj1.nested.a = 20; // both statement works
obj2.nested.a = 20;
謝謝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.