Was ist das Gegenteil von Object.freeze
oder Object.seal
? Gibt es eine Funktion mit einem Namen wie "Trennen"?
javascript
locking
freeze
Abdennour TOUMI
quelle
quelle
Antworten:
Es gibt keine Möglichkeit, dies zu tun. Sobald ein Objekt eingefroren wurde, gibt es keine Möglichkeit, es wieder einzufrieren.
Quelle
quelle
Object.freeze(obj); thirdPartyRoutine(obj); Object.unfreeze(obj); /*continue using obj*/
Ich denke, Sie können dies mit einigen Tricks tun:
Code hier:
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
Hinweis: Beachten Sie eines, tun Sie es nicht
tempObj = obj
, dann funktioniert es nicht, datempObj
es dort auch eingefroren ist.Geige hier: http://jsfiddle.net/mpSYu/
quelle
obj != tempObj
sind ihre Signaturen nicht mehr dieselben.obj
, jedoch nur im lokalen Bereich. ps Ich persönlich mag es, dass Objekte nicht ungefroren werden können.Kabelgebundene Lösung :)
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; }
Empfohlene Vorgehensweise :
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]
quelle
Object.assign
bessere Option. Allerdings ist eine Kopie / ein Klon auch nicht das, wonach ich sucheSie können ein eingefrorenes Objekt nicht auftauen.
Sie können es jedoch so gestalten, dass lästige Bibliotheken in Zukunft nichts mehr einfrieren können, indem Sie die Object.freeze-Methode als No-Op überschreiben:
Object.freeze = function(obj) { return obj; }; // just return the original object
In den meisten Fällen reicht dies aus. Führen Sie einfach den obigen Code aus, bevor die Bibliothek geladen wird, und sie kann nichts mehr einfrieren. ;; )
BEARBEITEN : Einige Bibliotheken, z. B.
[email protected]
, haben Probleme, es sei denn, dieObject.isFrozen(obj)
Rückgabe erfolgttrue
nach demObject.freeze(obj)
Aufruf.Das Folgende ist somit eine sicherere Methode zum Blockieren des Einfrierens von Objekten: (Die primitiven Überprüfungen sind auf
WeakSet
Fehler zurückzuführen, wenn Sie Primitive übergeben.)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); };
quelle
Object.freeze
funktioniert aus einem bestimmten Grund so.Sie können ein Objekt nicht auftauen (auftauen), aber wenn das Objekt einfach eine Sammlung von Grundelementen ist (keine Funktionen oder Klassen), können Sie einen aufgetauten Klon des Objekts wie folgt erhalten:
const unfrozenObj = JSON.parse(JSON.stringify(frozenObj));
quelle
Getestet in FF 52:
Soweit das (symbolische) 'Eltern'-Objekt des eingefrorenen Objekts (wo es symbolisch durch, neben / abgesehen von anderen symbolischen Verweisen in anderen Teilen des Codes auf dasselbe Objekt referenziert wird) NICHT GEFROREN ist (wie Fenster), kann man lösche es trotzdem durch den Löschoperator, - wie:
window.tinymce löschen;
selbst wenn window.tinymce VORHER von Object.freeze (window.tinymce) eingefroren wurde; (Andernfalls würde das 'Elternteil' selbst zu einer Art "eingefrorenem" Element, das eine nicht zerstörbare Objektreferenz enthält und das Symbol des NICHT eingefrorenen Elternteils nicht mehr löschbar macht ...)
Soweit man eine Kopie / Klon / Rekonstruktion / eigene Version / des Originalobjekts bereits vor dem Löschen / Entfernen erstellt hat, die keine / der ursprünglichen Einschränkungen (eingefroren, Erweiterbarkeit, Konfigurierbarkeit, Beschreibbarkeit usw.) beseitigt hat, man kann einen Verweis auf diese Kopie / Klon / Rekonstruktion / eigene Version / auf den ursprünglichen symbolischen Ort setzen / zuweisen - so:
window.tinymce = the_copy_clone_reconstruction_own_version_object;
Stellen Sie sicher, dass "copy_clone_reconstruction_own_version_object" im globalen Bereich vorhanden ist, damit es nicht gelöscht wird, nachdem Ihr Workaround-Code beendet wurde! [Eigentlich sollte das Objekt selbst gelöscht werden / es wird Speicher freigegeben / nur und nur dann, wenn der allerletzte Verweis darauf aus einem Bereich entfernt wurde - einige Zeit später aufgrund der Speicherbereinigung, aber ich bin mir nicht sicher, welche Priorität es hat höher als die 'Funktion beendet - alle lokalen Variablen löschen']
NICHT getestet: Andere symbolische Verweise KÖNNEN außerdem auf das ursprüngliche, eingefrorene / eingeschränkte Objekt verweisen - wie etwas, das als festgelegt wurde
myobj.subobj = window.tinymce;
bevor Ihre Operationen begannen.
Solche Sachen (myobj.subobj) werden wahrscheinlich (probieren Sie es aus!) Weiterhin auf das gefrorene Original (?) Zeigen.
nächste Vorstellung: NICHT getestet!
Was ist mit der 'Proxy'-Funktion, um Value-Get / Set und anderes Verhalten (Funktionen, ...) eines eingefrorenen / versiegelten oder anderweitig eingeschränkten (Erweiterbarkeit, ...) Objekts zu verpacken? Erstellt im GLOBAL-Bereich wie p = neuer Proxy (Ziel, Handler); oder window.p = neuer Proxy (Ziel, Handler);
// wobei target das Objekt ist, das zum Abfangen / Einhaken / Überwachen umbrochen werden soll, wie zum Beispiel "window.tinymce"
Das mdn-doc für das Proxy-Thema besagt, dass Einschränkungen (eingefroren, ...) des umschlossenen Objekts beibehalten werden, die sich jedoch auf das Core- / Original-Objekt selbst (vom Proxy umschlossen) beziehen und möglicherweise auch NICHT auf die Nachahmung durch den Proxy verweisen ...
Geltungsbereichsregeln können wie oben erwähnt gelten ...
quelle
Ich habe dieses Problem auch gelöst. Um dies zu beheben, habe ich die JavaScript-JSON-API verwendet, um mein Objekt freizugeben :
const unfreezeObject = JSON.parse(JSON.stringify(freezeObject))
. Danach habe ich alle Mutationen gemacht, die ich brauchte.quelle
{ ...item }
möglicherweise nur eine flache Kopie erforderlich.Ein wenig zu spät zur Party, aber Sie können auch ein Objekt in einer veränderlichen Variablen (
let
) erstellen und das ursprüngliche Objekt der Variablen neu zuweisen, wenn Sie es zurücksetzen müssen.Zum Beispiel:
let obj = { objProp: "example" }; if (condition) { Object.freeze(obj); } else { obj = { objProp: "example" }; }
quelle
Sie können ein Array mit dem Spread-Operator auftauen.
//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
quelle