我刚刚听说过JavaScript方法freeze
和seal
,它们可用于使任何对象不可变。
以下是如何使用它的简短示例:
var o1 = {}, o2 = {};
Object.freeze(o2);
o1["a"] = "worked";
o2["a"] = "worked";
alert(o1["a"]); //prints "worked"
alert(o2["a"]); //prints "undefined"
freeze
和seal
之间有什么区别?他们能提高绩效吗?
答案 0 :(得分:165)
delete
将返回false writable
为真,则更改其value
属性及其writeable
属性。TypeError
(最常见的是严格模式)Object.seal
的作用,加上:两者都不会影响'深'/孙子对象。例如,如果冻结obj
,则无法重新分配obj.el
,但可以修改obj.el
的值,例如obj.el.id
可以更改。
根据浏览器的不同,封闭或冻结对象可能会影响其枚举速度:
答案 1 :(得分:80)
答案 2 :(得分:74)
我写了一个test project来比较这三种方法:
Object.freeze()
Object.seal()
Object.preventExtensions()
我的单元测试涵盖了CRUD案例:
结果:
答案 3 :(得分:7)
Object.freeze()
创建一个冻结对象,这意味着它需要一个
现有的对象并且基本上在其上调用Object.seal()
,但它也是
将所有“数据访问者”属性标记为writable:false
,以便将其标记为{{1}}
值无法更改。 - Kyle Simpson,你不知道JS - 这个&对象原型
答案 4 :(得分:3)
我正在研究ECMAScript 5中Freeze和Seal之间的差异,并创建了一个脚本来澄清差异。 Frozen创建了一个包含数据和结构的不可变对象。 Seal阻止对命名接口的更改 - 不添加,删除 - 但您可以改变对象并重新定义其接口的含义。
function run()
{
var myObject = function()
{
this.test = "testing";
}
//***************************SETUP****************************
var frozenObj = new myObject();
var sealedObj = new myObject();
var allFrozen = Object.freeze(frozenObj);
var allSealed = Object.seal(sealedObj);
alert("frozenObj of myObject type now frozen - Property test= " + frozenObj.test);
alert("sealedObj of myObject type now frozen - Property test= " + sealedObj.test);
//***************************FROZEN****************************
frozenObj.addedProperty = "added Property"; //ignores add
alert("Frozen addedProperty= " + frozenObj.addedProperty);
delete frozenObj.test; //ignores delete
alert("Frozen so deleted property still exists= " + frozenObj.test);
frozenObj.test = "Howdy"; //ignores update
alert("Frozen ignores update to value= " + frozenObj.test);
frozenObj.test = function() { return "function"; } //ignores
alert("Frozen so ignores redefinition of value= " + frozenObj.test);
alert("Is frozen " + Object.isFrozen(frozenObj));
alert("Is sealed " + Object.isSealed(frozenObj));
alert("Is extensible " + Object.isExtensible(frozenObj));
alert("Cannot unfreeze");
alert("result of freeze same as the original object: " + (frozenObj === allFrozen).toString());
alert("Date.now = " + Date.now());
//***************************SEALED****************************
sealedObj.addedProperty = "added Property"; //ignores add
alert("Sealed addedProperty= " + sealedObj.addedProperty);
sealedObj.test = "Howdy"; //allows update
alert("Sealed allows update to value unlike frozen= " + sealedObj.test);
sealedObj.test = function() { return "function"; } //allows
alert("Sealed allows redefinition of value unlike frozen= " + sealedObj.test);
delete sealedObj.test; //ignores delete
alert("Sealed so deleted property still exists= " + sealedObj.test);
alert("Is frozen " + Object.isFrozen(sealedObj));
alert("Is sealed " + Object.isSealed(sealedObj));
alert("Is extensible " + Object.isExtensible(sealedObj));
alert("Cannot unseal");
alert("result of seal same as the original object: " + (sealedObj === allSealed).toString());
alert("Date.now = " + Date.now());
}
答案 5 :(得分:3)
答案 6 :(得分:2)
我知道我可能会迟到但
directives: [AddClass]
。在密封的地方
可写 属性设置为false
,其余属性为false。答案 7 :(得分:0)
现在可以强制冻结单个对象属性,而不是冻结整个对象。您可以使用rep_len(monthName, length(entry$test))
Object.defineProperty
作为参数来实现此目的。
writable: false
在此示例中,var obj = {
"first": 1,
"second": 2,
"third": 3
};
Object.defineProperty(obj, "first", {
writable: false,
value: 99
});
现在将其值锁定为99。