与 JavaScript 中的 Object.freeze 或 Object.seal 相对
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19293321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Opposite of Object.freeze or Object.seal in JavaScript
提问by Abdennour TOUMI
What is the opposite of Object.freeze
or Object.seal
? Is there a function that has a name such as detach?
Object.freeze
或的反义词是Object.seal
什么?是否有具有名称的函数,例如 detach?
回答by CodingIntrigue
There is no way to do this, once an object has been frozen there is no way to unfreeze it.
没有办法做到这一点,一旦对象被冻结,就无法解冻它。
Freezing an object is the ultimate form of lock-down. Once an object has been frozen it cannot be unfrozen – nor can it be tampered in any manner. This is the best way to make sure that your objects will stay exactly as you left them, indefinitely
冻结对象是锁定的最终形式。一旦对象被冻结,就无法解冻——也不能以任何方式篡改。这是确保您的对象将无限期地保持原样的最佳方式
回答by Ashish Kumar
I think you can do, using some tricks:
我认为你可以做到,使用一些技巧:
- First create a duplicate temporary variable of original object
- then set the original variable to undefined
- the reset the value of it from the temporary.
- 首先创建原始对象的重复临时变量
- 然后将原始变量设置为 undefined
- 从临时重置它的值。
Code here:
代码在这里:
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
Note: Keep one thing in mind, don't do tempObj = obj
, then it won't work because tempObj
is also frozen there.
注意:记住一件事,不要做tempObj = obj
,那么它就不会工作,因为tempObj
它也被冻结在那里。
Fiddle here: http://jsfiddle.net/mpSYu/
在这里小提琴:http: //jsfiddle.net/mpSYu/
回答by Abdennour TOUMI
Wired solution :)
有线解决方案:)
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;
}
Best Practices :
最佳实践:
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]
回答by Venryx
You can't unfreeze a frozen object.
您无法解冻冻结的对象。
You can however make it so pesky libraries can't freeze anything in the future, by overriding the Object.freeze method to be a no-op:
但是,您可以通过将 Object.freeze 方法覆盖为无操作来使讨厌的库在将来无法冻结任何内容:
Object.freeze = function(obj) { return obj; }; // just return the original object
In most cases this is enough. Just run the code above before the library is loaded, and it can no longer freeze anything. ; )
在大多数情况下,这就足够了。只需在加载库之前运行上面的代码,它就不能再冻结任何东西了。; )
回答by dos
Tested in FF 52:
在 FF 52 中测试:
As far as the frozen-object's (symbolic) 'parent'-object (where it is symbolically referenced by, beside/apart from other symbolic references in other parts of code to the same object) is NOT FROZEN (like window), one can delete it nonetheless by the delete-operator, - like:
至于冻结对象的(符号)“父”对象(它被符号引用,除了/除了代码其他部分中对同一对象的其他符号引用之外)不是 FROZEN(如窗口),可以尽管如此,还是通过删除操作符删除它,例如:
delete window.tinymce;
删除 window.tinymce;
even if window.tinymce had been frozen BEFORE by Object.freeze(window.tinymce); (otherwise the 'parent' would become some kind of "frozen" itself, as containing a non-destroyable object-reference, that would make the symbol of the NOT-frozen parent un-deletable ...)
即使 window.tinymce 在 Object.freeze(window.tinymce) 之前已经被冻结;(否则“父”本身会变成某种“冻结”,因为包含不可破坏的对象引用,这将使未冻结的父的符号不可删除......)
As far as one has a copy/clone/reconstruction/own version/ of the original object already made before deletion/removal, which got rid/has none/ of the original restrictions (frozen, extensibility, configurability, writeability and so on), one can put/assign a reference to that copy/clone/reconstruction/own version/ to the original symbolic place, - like that way:
至于删除/删除之前已经制作的原始对象的副本/克隆/重建/自己的版本/,它摆脱/没有/原始限制(冻结,可扩展性,可配置性,可写性等),可以将对该副本/克隆/重建/自己的版本/的引用放置/分配到原始符号位置,就像这样:
window.tinymce = the_copy_clone_reconstruction_own_version_object;
window.tinymce = the_copy_clone_reconstruction_own_version_object;
Make sure to have that "copy_clone_reconstruction_own_version_object" in the global scope for not being dropped after Your workaround-code has finished! [Actually the object itself should be dropped/it's memory freed/ just and only when the very last reference to it has been removed from any scope, - some time later, due to-garbage collection, but I'm not sure about the precedence higher than the 'function finished - drop all local vars']
确保在全局范围内有“copy_clone_reconstruction_own_version_object”,以免在您的解决方法代码完成后被删除![实际上,对象本身应该被删除/它的内存被释放/仅当对它的最后一个引用已从任何范围中删除时, - 一段时间后,由于垃圾收集,但我不确定优先级高于'功能完成 - 删除所有本地变量']
NOT tested: Other symbolic references MAY point to the original, frozen/restricted, object furthermore, - like something, which was set as
未测试:其他符号引用还可以指向原始的、冻结/受限的对象,例如设置为
myobj.subobj=window.tinymce;
myobj.subobj=window.tinymce;
before Your operations began.
在您的操作开始之前。
Stuff like that (myobj.subobj) will probably (give it a try!) furthermore point to the frozen original (?).
像这样的东西(myobj.subobj)可能会(试一试!)而且指向冻结的原件(?)。
next notion: NOT tested!
下一个概念:未测试!
What about to use the 'proxy'-feature to wrap value-get/-set and other behaviour (functions, ...) of a frozen/sealed or otherwise restricted (extensibility, ...) object?
Created at GLOBAL scope like
p = new Proxy(target, handler);
or
window.p = new Proxy(target, handler);
// where target is the object to wrap for interception/hooking/monitoring, as for instance "window.tinymce"
如何使用“代理”功能来包装冻结/密封或其他受限(可扩展性,...)对象的值获取/设置和其他行为(函数,...)?在 GLOBAL 范围内创建,如 p = new Proxy(target, handler); 或 window.p = new Proxy(target, handler);
// 其中 target 是为拦截/挂钩/监控而包装的对象,例如“window.tinymce”
The mdn-doc for the proxy-topic says, that restrictions (frozen, ...) of the wrapped object are kept regarded, but that could refer to the core-/original-object itself (wrapped by the proxy) and might eventually NOT refer to the mimic made by the proxy ...
代理主题的 mdn-doc 说,包装对象的限制(冻结,...)被保留,但这可能指的是核心/原始对象本身(由代理包装),最终可能不要指代代理所做的模仿......
Scope-rules might apply as mentioned above ...
如上所述,范围规则可能适用......
回答by joeytwiddle
You cannot unfreeze (thaw) an object, but if the object is simply a collection of primitives (no functions or classes), you can get a thawed clone of the object like this:
您不能解冻(解冻)一个对象,但如果该对象只是一个基元的集合(没有函数或类),您可以像这样获得一个解冻的对象克隆:
const unfrozenObj = JSON.parse(JSON.stringify(frozenObj));
回答by abbah
I was issue that problem too. TO fix it, I used JavaScript JSON API to unfreeze my object: const unfreezeObject = JSON.parse(JSON.stringify(freezeObject))
. After, I did all mutations I needed.
我也是这个问题。为了修复它,我使用 JavaScript JSON API 来解冻我的对象:const unfreezeObject = JSON.parse(JSON.stringify(freezeObject))
. 之后,我做了我需要的所有突变。
回答by Pawan Mittal
You can unfreeze an array by using spread operator.
您可以使用扩展运算符解冻数组。
//let suppose arr is a frozen array i.e. immutable
var arr = [1, 2, 3];
//if arr is frozen arr you cannot mutate any array referring to it
var temp = arr;
temp.push(4); //throws an error "Cannot modify frozen array elements"
//here mutableArr gets the elements of arr but not reference to it
//hence you can mutate the mutableArr
var mutableArr = [...arr];
mutableArr.push(4); //executes successfully