What is the opposite of Object.freeze
or Object.seal
? Is there a function that has a name such as detach?
I think you can do, using some tricks:
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/
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. ; )
EDIT: Some libraries, such as immer@7.0.7
, have issues unless Object.isFrozen(obj)
returns true
after Object.freeze(obj)
is called.
The below is thus a safer way of blocking object-freezing: (the primitive checks are because WeakSet
errors if you pass in primitives)
const fakeFrozenObjects = new WeakSet();
function isPrimitive(val) {
return val == null || (typeof val != "object" && typeof val != "function");
}
Object.freeze = obj=>{
if (!isPrimitive(obj)) fakeFrozenObjects.add(obj);
return obj;
};
Object.isFrozen = obj=>{
if (isPrimitive(obj)) return true;
return fakeFrozenObjects.has(obj);
};
A little late to the party, but you can also create an object in a mutable variable (let
), and reassign the original object to the variable when you need to reset it.
For example:
let obj = { objProp: "example" };
if (condition) {
Object.freeze(obj);
}
else {
obj = { objProp: "example" };
}
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 ...
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
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