Javascript Object.freeze()不会阻止对对象的更改 [英] Javascript Object.freeze() does not prevent changes to object

查看:25
本文介绍了Javascript Object.freeze()不会阻止对对象的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆