Opposite of Object.freeze or Object.seal in JavaScript

Javascript

Javascript Problem Overview


What is the opposite of Object.freeze or Object.seal? Is there a function that has a name such as detach?

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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/

Solution 3 - Javascript

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]

Solution 4 - Javascript

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 [email protected], 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);
};

Solution 5 - Javascript

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));

Solution 6 - Javascript

Based on the answers and comments it seems that people find this post when they need to mutate a frozen object. Saying "that's impossible" while accurate, is not all that helpful.

With that in mind here's the modern variation I came up with based on @Abdennour TOUMI answer from 2014

function unfreeze(obj) {
  if (Object.isFrozen(obj)) {
    return Object.assign({}, obj);
  }
  return obj;
}

Here's an example on how to use it:

let myObj = { one: "1", two: "2", three: "3" };
Object.freeze(myObj);
// error
// myObj.one = "4";
// succeeds
myObj = unfreeze(myObj);
myObj.one = "4";

Solution 7 - Javascript

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 ...

Solution 8 - Javascript

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.

Solution 9 - Javascript

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" };
}

Solution 10 - Javascript

I think that if you wanted to keep the original object, but still have unfrozen behaviour, then the only logic still left would be to create a subclass with the same behaviour of the original object, and then internal to the subclass, you would override the behaviour of the existing object by creating accessors that are mutable, which override the ones you want to change.

This way, if you still want the original variable/object alive for some strange reason, or to keep the rest of the system consistent, then you can leave it alone, but have the benefit of its existing behaviour while using the subclass version inheriting directly from the original without necessarily redoing the original parent object. I cannot see how trying the impossible or the illogical seems to be such a desirable thing. You can't have your cake, eat it, then want to still have all of the original cake left, unless you subclass...

Otherwise you are just being impossible.

Solution 11 - Javascript

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 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbdennour TOUMIView Question on Stackoverflow
Solution 1 - JavascriptCodingIntrigueView Answer on Stackoverflow
Solution 2 - JavascriptAshish KumarView Answer on Stackoverflow
Solution 3 - JavascriptAbdennour TOUMIView Answer on Stackoverflow
Solution 4 - JavascriptVenryxView Answer on Stackoverflow
Solution 5 - JavascriptjoeytwiddleView Answer on Stackoverflow
Solution 6 - JavascriptMichael SorensenView Answer on Stackoverflow
Solution 7 - JavascriptdosView Answer on Stackoverflow
Solution 8 - JavascriptAbbahView Answer on Stackoverflow
Solution 9 - JavascriptSJCypherView Answer on Stackoverflow
Solution 10 - JavascriptRaoulView Answer on Stackoverflow
Solution 11 - JavascriptPawan MittalView Answer on Stackoverflow