我正在尝试了解ECMAscript的Object.freeze方法。
我的理解是,它实质上停止了对对象所有属性的更改。MDN文档说:
防止向其添加新属性;防止现有属性被删除;并防止更改现有属性或其可枚举性,可配置性或可写性。
似乎并非如此,但也许我误解了文档。
这是我的对象,它具有可枚举的属性exampleArray
function myObject()
{
    this.exampleArray = [];
}
var obj = new myObject();
obj.exampleArray[0] = "foo";
现在,如果我冻结对象,我希望exampleArray属性也将被冻结,因为无法再以任何方式对其进行更改。
Object.freeze(obj);
obj.exampleArray[1] = "bar";
console.log(obj.exampleArray.length); // logs 2
“ bar”已添加到数组,因此冻结的对象已更改。我的直接解决方案是冻结所需的属性:
Object.freeze(obj.exampleArray);
obj.exampleArray[2] = "boo";
现在,根据需要更改数组会引发错误。
但是,我正在开发我的应用程序,但我还不知道将为对象分配什么。我的用例是,我有一些游戏对象在游戏开始时被初始化(来自XML文件)。此后,我不希望能够意外更改其任何属性。
也许我滥用冻结方法?我希望能够冻结整个对象,这是一种递归冻结。我能想到的最好的解决方案是遍历属性并冻结每个属性。
我已经搜索了这个问题,唯一的回答是这是一个实现错误。我正在使用最新版本的Chrome。任何帮助表示赞赏。
Object.freeze是一个浅冻结。
如果您查看文档中的描述,它会说:
不能更改数据属性的值。访问器属性(获取器和设置器)的工作原理相同(并且仍然给人一种幻想,即您正在更改值)。请注意,除非将对象值冻结,否则仍可以对其进行修改。
如果要深度冻结对象,这是一个很好的递归示例
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