我刚刚听说过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
?它们可以提高性能吗?
- 它防止在密封物体上增加和/或去除特性;使用
delete
将返回false - 它使每个现有属性都不可配置:它们无法从“数据描述符”转换为“访问器描述符”(反之亦然),并且根本无法修改访问器描述符的属性(而数据描述符可以更改其
writable
属性,并且其value
属性(如果writeable
为true)。 TypeError
尝试修改密封对象本身的值时会抛出一个(通常在严格模式下)
- 究竟是什么
Object.seal
,再加上: - 它防止修改任何现有属性
都不会影响“深” /孙子对象。例如,如果obj
冻结,obj.el
则无法重新分配,但是obj.el
可以修改的值,例如obj.el.id
可以更改。
性能:
密封或冻结对象可能会影响其枚举速度,具体取决于浏览器:
- Firefox:枚举性能不受影响
- IE:枚举性能的影响可以忽略不计
- Chrome:对于密封或冻结的对象,枚举性能更快
- Safari:密封或冻结的物体枚举速度降低了92%(截至2014年)
我写了一个测试项目,比较了这三种方法:
Object.freeze()
Object.seal()
Object.preventExtensions()
我的单元测试涵盖了CRUD案例:
- [C]添加新属性
- [R]读取现有属性
- [U]修改现有属性
- [D]删除现有财产
结果:
您始终可以在MDN中查找这些内容。简而言之:
Object.freeze()
创建一个冻结的对象,这意味着它需要一个现有的对象并从本质Object.seal()
上对其进行调用,但是它还将所有“数据访问器”属性标记为writable:false
,因此它们的值不能更改。-Kyle Simpson,您不懂JS-此和对象原型
我正在研究ECMAScript 5中的Freeze和Seal之间的差异,并创建了一个脚本来阐明差异。冻结会创建一个包含数据和结构的不可变对象。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());
}
我知道我可能迟到了
- 相似性:它们都用于创建不可扩展的对象。
- 区别:在“冻结”中,
对象的可配置,可枚举和可写属性设置为false
。其中,如Sealed
可写属性设置为true
,其余属性为false。
现在,您可以强制冻结单个对象属性,而不是冻结整个对象。您可以Object.defineProperty
使用writable: false
作为参数来实现。
var obj = {
"first": 1,
"second": 2,
"third": 3
};
Object.defineProperty(obj, "first", {
writable: false,
value: 99
});
在此示例中,obj.first
现在将其值锁定为99。
本文地址:http://javascript.askforanswer.com/dongjiehemifengzhijiandequbie.html
文章标签:ecmascript-5 , javascript
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
文章标签:ecmascript-5 , javascript
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!