What is the opposite of Object.freeze
or Object.seal
? Is there a function that has a name such as detach?
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
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/
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]
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. ; )
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 ...
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));
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
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.
I tried this one and it is working fine
let obj = {name:'Trickester', age:25}
Object.freeze(obj)
let newObj = obj
obj = null
obj = newObj
//make whatever changes you
来源:https://stackoverflow.com/questions/19293321/opposite-of-object-freeze-or-object-seal-in-javascript