web-dev-qa-db-fra.com

Opposite de Object.freeze ou Object.seal en JavaScript

Quel est le contraire de Object.freeze ou Object.seal? Existe-t-il une fonction qui porte un nom tel que detach?

51
Abdennour TOUMI

Il n'y a aucun moyen de le faire, une fois qu'un objet a été gelé, il n'y a aucun moyen de le dégeler.

La source

Geler un objet est la forme ultime de verrouillage. Une fois un objet a été gelé il ne peut pas être dégelé - il ne peut pas être altéré dans aucun manière. C’est le meilleur moyen de s’assurer que vos objets resteront exactement comme vous les avez laissés, indéfiniment

72
CodingIntrigue

Je pense que vous pouvez faire, en utilisant quelques astuces:

  • Commencez par créer une variable temporaire en double de l'objet d'origine.
  • puis définissez la variable d'origine sur non définie
  • la réinitialiser la valeur de la temporaire.

Code ici:

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: N'oubliez pas une chose, ne faites pas tempObj = obj, alors cela ne fonctionnera pas car tempObj est également figé à cet endroit.

Fiddle here: http://jsfiddle.net/mpSYu/

13
Ashish Kumar

Solution filaire :)

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

Les meilleures pratiques :


 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]
6
Abdennour TOUMI

Vous ne pouvez pas dégeler un objet gelé.

Vous pouvez cependant faire en sorte que les bibliothèques embêtantes ne puissent plus geler quoi que ce soit dans le futur, en substituant la méthode Object.freeze à une opération no-op:

Object.freeze = function(obj) { return obj; }; // just return the original object

Dans la plupart des cas, cela suffit. Il suffit d’exécuter le code ci-dessus avant que la bibliothèque ne soit chargée et elle ne peut plus rien geler. ; )

2
Venryx

Testé à 52 FF:

Pour autant que l'objet parent (symbolique) (symbolique) (où il est référencé symboliquement par, à côté/à part des références symboliques dans d'autres parties de code du même objet) n'est PAS FROZEN (comme une fenêtre), on peut le supprime néanmoins par l'opérateur delete, - comme:

supprimer window.tinymce;

même si window.tinymce avait été gelé AVANT par Object.freeze (window.tinymce); (sinon le "parent" deviendrait une sorte de "gelé" lui-même, comme contenant une référence d'objet non destructible, rendre le symbole du parent NON-congelé non supprimable ...)

Dans la mesure où on a une copie/clone/reconstruction/version propre/de l'objet original déjà faite avant suppression/suppression, qui s'est débarrassée/n'a aucune/des restrictions d'origine (blocage, extensibilité, configurabilité, possibilité d'écriture, etc.), on peut mettre/assigner une référence à cette copie/clone/reconstruction/propre version/à l'endroit symbolique original, - comme ça:

window.tinymce = the_copy_clone_reconstruction_own_version_object;

Assurez-vous que "copy_clone_reconstruction_own_version_object" figure dans la portée globale afin de ne pas être supprimé après la fin de votre code de contournement! [En fait, l'objet doit être supprimé/sa mémoire libérée/uniquement et uniquement à la dernière référence. a été supprimé de n'importe quelle portée, quelque temps plus tard, en raison de la récupération de place, mais je ne suis pas sûr de la priorité supérieure à la 'fonction terminée - supprime tous les vars locaux']

NON testé: D'autres références symboliques PEUVENT pointer sur l'objet d'origine, gelé/restreint, - comme quelque chose qui a été défini comme 

myobj.subobj = window.tinymce;

avant que vos opérations ont commencé.

Des trucs comme ça (myobj.subobj) vont probablement (essayez-les!) Indiquer en outre l'original figé (?).

notion suivante: NON testé!

Que diriez-vous d'utiliser la fonctionnalité 'proxy' pour envelopper la valeur-get/-set et d'autres comportements (fonctions, ...) d'un objet gelé/scellé ou autrement restreint (extensibilité, ...)? Créé à Portée globale comme p = nouveau proxy (cible, gestionnaire); ou window.p = nouveau proxy (cible, gestionnaire);
// où cible est l'objet à emballer pour l'interception/le raccordement/la surveillance, comme par exemple "window.tinymce"

Le mdn-doc pour le proxy-topic indique que les restrictions (congelées, ...) de l'objet enveloppé sont conservées, mais que cela pourrait faire référence à l'objet principal/original lui-même (enveloppé par le proxy) et pourrait éventuellement NE PAS se référer à l'imitation faite par le proxy ...

Les règles de portée peuvent s'appliquer comme mentionné ci-dessus ...

1
dos

J'ai essayé celui-ci et ça marche bien

let obj = {name:'Trickester', age:25}
 Object.freeze(obj)
 let newObj = obj
 obj = null
 obj = newObj
 //make whatever changes you 

0
Dev Gaud

Vous ne pouvez pas dégeler (dégeler) un objet, mais si l’objet est simplement une collection de primitives (sans fonctions ni classes), vous pouvez obtenir un clone décongelé de l’objet comme ceci:

const unfrozenObj = JSON.parse(JSON.stringify(frozenObj));
0
joeytwiddle

J'ai été problème ce problème aussi. Pour résoudre ce problème, j'ai utilisé l'API JSON JavaScript pour libérer mon objet: const unfreezeObject = JSON.parse(JSON.stringify(freezeObject)). Après, j'ai fait toutes les mutations dont j'avais besoin.

0
abbah

Vous pouvez dégeler un tableau en utilisant l'opérateur spread.

//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 
0
Pawan Mittal