Javascript Object.freeze()不会阻止对对象的更改 [英] Javascript Object.freeze() does not prevent changes to object
问题描述
我试图了解ECMAscript的Object.freeze方法.
I am trying to understand the Object.freeze method of ECMAscript.
我的理解是,它实质上停止了对对象所有属性的更改.MDN文档说:
My understanding was that it essentially stops changes to all the properties of an object. MDN documentation says:
防止新属性被添加到其中;防止删除现有属性;并防止更改现有属性或其可枚举性,可配置性或可写性.
Prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed.
似乎并非如此,但也许我误解了文档.
This does not seem to be the case, but perhaps I have misinterpreted the docs.
这是我的对象,它具有可枚举的属性exampleArray
Here is my object, with its enumerable property exampleArray
function myObject()
{
this.exampleArray = [];
}
var obj = new myObject();
obj.exampleArray[0] = "foo";
现在,如果我冻结对象,那么我也希望exampleArray属性也被冻结,因为无法再以任何方式对其进行更改.
Now if I freeze the object, I would expect the exampleArray property to be frozen too, as in it can no longer be changed in any way.
Object.freeze(obj);
obj.exampleArray[1] = "bar";
console.log(obj.exampleArray.length); // logs 2
"bar"已添加到数组,因此冻结的对象已更改.我立即的解决方案是冻结所需的属性:
"bar" has been added to the array, thus the frozen object has been changed. My immediate solution is to just freeze the desired property:
Object.freeze(obj.exampleArray);
obj.exampleArray[2] = "boo";
现在,根据需要更改数组会引发错误.
Now changing the array throws an error, as desired.
但是,我正在开发我的应用程序,但是我还不知道将分配给我的对象什么.我的用例是,我有一些游戏对象在游戏开始时被初始化(来自XML文件).此后,我不想意外更改它们的任何属性.
However, I am developing my application and I don't yet know what will be assigned to my object. My use case is that I have some game objects which are initialized (from an XML file) when the game starts. After this, I do not want to be able to change any of their properties accidentally.
也许我误用了冻结方法?我希望能够冻结整个对象,这是一种递归冻结.我在这里可以想到的最好的解决方案是遍历属性并冻结每个属性.
Perhaps I am misusing the freeze method? I would like to be able to freeze the whole object, a sort of recursive freeze. The best solution I can think of here is to loop through the properties and freeze each one.
我已经搜索了这个问题,唯一的回答是这是一个实现错误.我正在使用最新版本的Chrome.任何帮助表示赞赏.
I've already searched for this question and the only answer says it's an implementation bug. I am using the newest version of Chrome. Any help is appreciated.
推荐答案
Object.freeze是一种浅冻结.
Object.freeze is a shallow freeze.
如果您查看文档,它说:
不能更改数据属性的值.访问器属性(获取器和设置器)的工作原理相同(并且仍然给人一种幻想,即您正在更改该值).请注意,除非已冻结对象对象的值,否则仍可以对其进行修改.
如果要深度冻结对象,请使用良好的递归方法例子
If you want to deep-freeze an object, here's a good recursive example
function deepFreeze(o) {
Object.freeze(o);
Object.getOwnPropertyNames(o).forEach(function(prop) {
if (o.hasOwnProperty(prop)
&& o[prop] !== null
&& (typeof o[prop] === "object" || typeof o[prop] === "function")
&& !Object.isFrozen(o[prop])) {
deepFreeze(o[prop]);
}
});
return o;
}
function myObject() {
this.exampleArray = [];
}
var obj = deepFreeze(new myObject());
obj.exampleArray[0] = "foo";
console.log(obj); // exampleArray is unchanged
这篇关于Javascript Object.freeze()不会阻止对对象的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!