2013-10-10 20 views

回答

57

有没有办法做到这一点,一旦一个对象被冻结,没有办法解冻它。

Source

冻结一个目的是向下锁定的最终形式。一旦对象 被冻结,它就不能被解冻 - 也不能以任何方式被篡改。这是为了确保我认为你能做的最好的方式,你的对象将保持 完全一样,你离开了他们,无限期

+7

这是技术上正确的,只要改变现有的对象。但是,您可以复制/克隆现有对象并立即改变它的属性。请参阅Andennour TOUMI(http://stackoverflow.com/a/26752410/1251309)的答案,了解如何完成此操作。 –

+0

只要解冻调用发生在同一范围内,只要对象可以解冻,就可以成为SWEEEEET。这将大大节省内存使用量,以避免克隆。 F.E. 'Object.freeze(OBJ); thirdPartyRoutine(OBJ); Object.unfreeze(OBJ);/*继续使用obj * /' – trusktr

11

,使用一些技巧:

  • 首先创建的副本临时变量原始对象
  • 然后将原始变量设置为undefined
  • 将其重置为临时值。

代码在这里:

var obj = {a : 5}; 

console.log(obj); // {a: 5} 
Object.freeze(obj); 

obj.b = 10; // trying to add something to obj var 
console.log(obj); // output: {a: 5} -> means its frozen 

// Now use this trick 
var tempObj = {}; 
for(var i in obj){ 
    tempObj[i] = obj[i]; 
} 
console.log(tempObj); // {a: 5} 

// Resetting obj var 
obj = tempObj; 
console.log(obj);// {a: 5} 

obj.b = 10; // trying to add something to obj var 
console.log(obj); // output: {a: 5, b: 10} -> means it's not frozen anymore 

注:保持一件事记住,不做tempObj = obj,那么它将无法工作,因为tempObj也被冻结在那里。

小提琴这里:http://jsfiddle.net/mpSYu/

+1

增强可见性:http://jsfiddle.net/abdennour/mpSYu/1/ –

+1

我明白你在做什么。复制这些值是一种“避开”冻结对象的方式,但在所有结束时,它们的签名不再相同。 – CodingIntrigue

+0

但是,冻结的对象可以删除!所以,现在这可能是一个可接受的解决方案。克隆冻结的对象并分配给相同的引用,然后删除冻结的对象将使我们回到原来的状态,只有手动克隆它的缺点。当然,我们失去了原来的一个。 –

8

有线解决方案:)

Object.unfreeze=function(o){ 
     var oo=undefined; 
     if(o instanceof Array){ 
       oo=[];var clone=function(v){oo.push(v)}; 
       o.forEach(clone); 
     }else if(o instanceof String){ 
      oo=new String(o).toString(); 
     }else if(typeof o =='object'){ 

     oo={}; 
     for (var property in o){oo[property] = o[property];} 


     } 
     return oo; 
} 

最佳实践:


var obj={a:1,b:2} 
// {a:1,b:2} 
    obj.c=3; 
    //{a:1,b:2,c:3} 
    Object.freeze(obj) 
    //{a:1,b:2,c:3} 
    obj.d=5; 
    //Error: Read only object 
    obj=Object.unfreeze(obj) 
    //{a:1,b:2,c:3} 
    obj.d=5; 
    //{a:1,b:2,c:3,d:5} 

var tab=[1,2,3] 
//[1,2,3] 
tab.push(4) 
//[1,2,3,4] 
Object.freeze(tab); 
//[1,2,3,4] 
tab.push(5) 
// Error : Ready only object 
tab=Object.unfreeze(tab); 
//[1,2,3,4] 
tab.push(9) 

//[1,2,3,4,9] 
+1

这应该是被接受的答案。尽管其他答案在技术上是正确的,但它完成了OP的任务。 –

+15

这不会解冻,这复制对象,完全不同的东西 –

+2

为记录,这个问题的所有答案都是错误的,并涉及一个NEW副本,outscopes仍然冻结的对象... – Leathan

1

您无法解冻冻结的物体。

但是,您可以使它这样讨厌的库不能在未来冻结任何东西,通过重写Object.freeze方法是一种无操作:

Object.freeze = function(obj) { return obj; }; // just return the original object 

在大多数情况下,这已经足够了。在加载库之前,只需运行上面的代码,它不能再冻结任何东西。 ; )

+0

这对我来说似乎很合理,就像一个反向垫片。为什么这是downvoted? – amay0048

+3

@ amay0048垫片*增加*行为。这*消除了现有的行为。这是一个可怕的想法,绝对不应该用于生产。 'Object.freeze'的工作方式是有原因的。 – CodingIntrigue

+0

使用垫片去除生产中的行为是一个可怕的想法。另一方面,如果你想破解,你可以做任何你想实现你的目标。 – mjz19910

1

测试在FF 52:

至于冷冻对象的(符号)“parent'对象(它被象征通过引用,旁/除了在对其他代码部分的其它符号引用相同的对象)不是冷冻的(如窗口),但可以通过删除操作符将其删除,例如:

delete window.tinymce;

即使窗口。tinymce已被Object.freeze(window.tinymce)冻结; (否则'父母'会变成某种“冻结”本身,因为含有不可破坏的对象引用,这将使得非冻结父对象的符号不可删除...)

As就像一个人在删除/删除之前已经创建了原始对象的拷贝/克隆/重建/自己的版本/原来的限制(冻结,可扩展性,可配置性,可写性等)可以将该副本/克隆/重建/自己版本/对该原始符号地点的引用分配/分配, - 像这样:

window.tinymce = the_copy_clone_reconstruction_own_version_object;

请确保在全局范围内有“copy_clone_reconstruction_own_version_object”,以便您的解决方法代码完成后不会被丢弃! [实际上,对象本身应该被删除/它的内存被释放/只是当它的最后一个引用已经从任何作用域中删除时 - 稍后由于垃圾收集,但我不确定优先级比更高“要完成的功能 - 删除所有本地变量”]

没有经过测试: 其他符号引用可能指向原来,冷冻/限制,对象此外, - 喜欢的事,这是设置为

myobj.subobj = window.tinymce;

您的操作开始之前。

这样的东西(myobj.subobj)可能会(试一试!)还指向冻结的原始(?)。

下一个概念: 未经测试!

如何使用'proxy'-feature来封装冻结/密封或其他限制(扩展性,...)对象的value-get/-set和其他行为(函数,...)? 在GLOBAL范围创建,如 p =新代理(目标,处理程序); 或 window.p =新代理(目标,处理程序);
//其中目标是要拦截/挂接/监视的对象,例如“window.tinymce”

代理主题的mdn-doc表示,限制(冻结,...)被包装的对象被认为是被保留的,但是这可能指的是核心/原始对象本身(被代理包裹)并且可能最终不会引用由代理所做的模仿...

范围规则可能适用于上述...