问题
What is the opposite of Object.freeze
or Object.seal
? Is there a function that has a name such as detach?
回答1:
There is no way to do this, once an object has been frozen there is no way to unfreeze it.
Source
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
回答2:
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.
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.
Fiddle here: http://jsfiddle.net/mpSYu/
回答3:
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]
回答4:
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 = 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. ; )
回答5:
Tested in 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:
delete 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 ...)
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;
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']
NOT tested: Other symbolic references MAY point to the original, frozen/restricted, object furthermore, - like something, which was set as
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 (?).
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"
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 ...
Scope-rules might apply as mentioned above ...
回答6:
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));
回答7:
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.
回答8:
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
来源:https://stackoverflow.com/questions/19293321/opposite-of-object-freeze-or-object-seal-in-javascript