javascript-objects löschen - Wie entferne ich eine Eigenschaft aus einem JavaScript-Objekt?



cookie delete (25)

Angenommen, ich erstelle ein Objekt wie folgt:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

Wie entferne myObject die Eigenschaftsausdehnung am besten, um mit myObject wie folgt myObject zu werden?

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};

Answers

const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)


Der Begriff, den Sie in Ihrem Remove a property from a JavaScript object , kann auf verschiedene Weise interpretiert werden. Die eine ist es, den gesamten Speicher und die Liste der Objektschlüssel zu entfernen, oder die andere, sie einfach aus Ihrem Objekt zu entfernen. Wie bereits in anderen Antworten erwähnt, ist das Schlüsselwort delete der Hauptbestandteil. Nehmen wir an, Sie haben Ihr Objekt wie:

myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

Wenn Sie tun:

console.log(Object.keys(myJSONObject));

Das Ergebnis wäre:

["ircEvent", "method", "regex"]

Sie können diesen bestimmten Schlüssel wie folgt aus Ihren Objektschlüsseln löschen:

delete myJSONObject["regex"];

Dann wäre Ihr Objektschlüssel mit Object.keys(myJSONObject) :

["ircEvent", "method"]

Wenn Sie sich jedoch um den Speicher kümmern und das gesamte Objekt aus dem Speicher entfernen möchten, empfiehlt es sich, den Wert auf null zu setzen, bevor Sie den Schlüssel löschen:

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

Der andere wichtige Punkt hier ist, dass Sie auf Ihre anderen Verweise auf dasselbe Objekt achten. Zum Beispiel, wenn Sie eine Variable erstellen wie:

var regex = myJSONObject["regex"];

Oder fügen Sie es als neuen Zeiger auf ein anderes Objekt hinzu:

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

Auch wenn Sie es aus Ihrem Objekt myJSONObject entfernen, wird dieses bestimmte Objekt nicht aus dem Speicher gelöscht, da die regex Variable und myOtherObject["regex"] noch ihre Werte haben. Wie können wir dann das Objekt sicher aus dem Speicher entfernen?

Die Antwort wäre, alle Verweise, die Sie in Ihrem Code haben, zu löschen , auf dasselbe Objekt zu verweisen und keine var Anweisungen zu verwenden, um neue Verweise auf dieses Objekt zu erstellen . Dieser letzte Punkt in Bezug auf var Anweisungen ist eines der wichtigsten Probleme, mit denen wir normalerweise konfrontiert sind, da die Verwendung von var Anweisungen verhindern würde, dass das erstellte Objekt entfernt wird.

Das bedeutet in diesem Fall, dass Sie das Objekt nicht entfernen können, weil Sie die regex Variable über eine var Anweisung erstellt haben.

delete regex; //False

Das Ergebnis wäre false , was bedeutet, dass Ihre Löschanweisung nicht wie erwartet ausgeführt wurde. Wenn Sie diese Variable jedoch zuvor nicht erstellt hätten und Sie lediglich myOtherObject["regex"] als letzte vorhandene Referenz verwendet hätten, hätten Sie dies einfach tun können, indem Sie sie wie myOtherObject["regex"] entfernen:

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

Mit anderen Worten, ein JavaScript-Objekt wird abgebrochen, sobald in Ihrem Code kein Verweis mehr vorhanden ist, der auf dieses Objekt verweist.

Update: Danke an @AgentME:

Wenn Sie eine Eigenschaft vor dem Löschen auf null setzen, wird nichts erreicht (es sei denn, das Objekt wurde durch Object.seal versiegelt und das Löschen schlägt fehl. Dies ist normalerweise nicht der Fall, wenn Sie es nicht ausdrücklich versuchen).

Weitere Informationen erhalten Sie unter Object.seal: Object.seal()


So was:

delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];

Demo

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};
delete myObject.regex;

console.log(myObject);

Für alle, die mehr darüber kangax hat der Benutzer von einen unglaublich ausführlichen Blogbeitrag über die kangax in seinem Blog geschrieben: " Verstehen löschen" . Es wird dringend empfohlen.


Object.assign () & Object.keys () & Array.map ()

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);


Die Delete- Methode ist der beste Weg, um dies zu tun. Gemäß der MDN-Beschreibung entfernt der Delete-Operator eine Eigenschaft aus einem Objekt. Sie können also einfach schreiben:

delete myObject.regex;
// OR
delete myObject['regex'];

Der delete-Operator entfernt eine bestimmte Eigenschaft aus einem Objekt. Bei erfolgreicher Löschung wird true zurückgegeben, andernfalls wird false zurückgegeben. Es ist jedoch wichtig, die folgenden Szenarien zu berücksichtigen:

  • Wenn die Eigenschaft, die Sie löschen möchten, nicht vorhanden ist, hat delete keine Auswirkungen und gibt true zurück

  • Wenn eine Eigenschaft mit demselben Namen in der Prototypkette des Objekts vorhanden ist, verwendet das Objekt nach dem Löschen die Eigenschaft aus der Prototypkette (dh, Löschen hat nur Auswirkungen auf die eigenen Eigenschaften).

  • Mit var deklarierte Eigenschaften können nicht aus dem globalen Bereich oder aus dem Funktionsbereich einer Funktion gelöscht werden.

  • Delete kann daher keine Funktionen im globalen Bereich löschen (unabhängig davon, ob dies Teil einer Funktionsdefinition oder einer Funktion (Ausdruck) ist.

  • Funktionen, die Teil eines Objekts sind (abgesehen vom
    globalen Gültigkeitsbereich), können mit delete gelöscht werden.

  • Mit let oder const deklarierte Eigenschaften können nicht aus dem Bereich gelöscht werden, in dem sie definiert wurden. Nicht konfigurierbare Eigenschaften können nicht entfernt werden. Dazu gehören Eigenschaften von integrierten Objekten wie Math, Array, Object und Eigenschaften, die mit Methoden wie Object.defineProperty () als nicht konfigurierbar erstellt werden.

Der folgende Ausschnitt zeigt ein weiteres einfaches Beispiel:

var Employee = {
      age: 28,
      name: 'abc',
      designation: 'developer'
    }
    
    console.log(delete Employee.name);   // returns true
    console.log(delete Employee.age);    // returns true
    
    // When trying to delete a property that does 
    // not exist, true is returned 
    console.log(delete Employee.salary); // returns true

Weitere Informationen und weitere Beispiele finden Sie unter dem folgenden Link:

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…


Versuchen Sie die folgende Methode. Weisen Sie den ObjectEigenschaftswert zu zu undefined. Dann stringifydas Objekt und parse.

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);


Update 2018-07-21: Ich habe mich lange Zeit mit dieser Antwort in Verlegenheit gebracht, daher denke ich, es ist an der Zeit, dass ich sie etwas aufbessere. Nur ein kleiner Kommentar, eine Klarstellung und eine Formatierung, um das Lesen der unnötig langen und komplizierten Teile dieser Antwort zu beschleunigen.

DIE KURZE VERSION

Die eigentliche Antwort auf die Frage

Wie andere schon gesagt haben, können Sie delete .

obj // {"foo": "bar"}
delete obj["foo"]
obj // {}
obj["foo"] // undefined

Array-Äquivalent

Nicht aus einem Array delete Verwenden Array.prototype.splice stattdessen Array.prototype.splice .

arr // [1,2,3,4,5]
arr.splice(3,1); // 4
arr // [1,2,3,5]

DIE LANGE VERSION

JavaScript ist eine OOP-Sprache, daher ist alles ein Objekt, einschließlich Arrays . Daher halte ich es für notwendig, auf einen bestimmten Vorbehalt hinzuweisen.

Im Gegensatz zu einfachen alten Objekten hinterlässt der delete in Arrays den Müll in Form von null , wodurch ein "Loch" im Array entsteht.

var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
 * Actual result   --> [1, 2, null, 4]
 */

Wie Sie sehen, funktioniert das delete nicht immer so, wie Sie es erwarten. Der Wert wird überschrieben, der Speicher wird jedoch nicht neu zugewiesen. Das heißt, array[4] wird nicht in array[3] . Im Gegensatz zu Array.prototype.unshift , das ein Element am Anfang des Arrays einfügt und alles nach oben Array.prototype.unshift ( array[0] wird zu array[1] usw.).

Ehrlich gesagt, abgesehen von dem Setzen auf null und nicht undefined - was recht seltsam ist - sollte dieses Verhalten nicht überraschen, da delete ein unärer Operator ist, wie typeof , der hart in die Sprache eingearbeitet ist und sich nicht darum kümmern sollte Der Typ des Objekts, für das er verwendet wird, während Array eine Unterklasse von Object mit Methoden ist, die speziell für das Arbeiten mit Arrays entwickelt wurden. Es gibt also keinen guten Grund für das delete , um einen speziellen Fall für das erneute Verschieben des Arrays einzurichten, da dies die Arbeit mit unnötiger Arbeit verlangsamen würde. Rückblickend waren meine Erwartungen unrealistisch.

Natürlich hat es mich überrascht. Weil ich dies geschrieben habe, um meinen Kreuzzug gegen "Nullmüll" zu rechtfertigen:

Das Ignorieren der Gefahren und Probleme, die mit null einhergehen, und der Platz, der verschwendet wird, kann problematisch sein, wenn das Array genau sein muss.

Was eine schreckliche Rechtfertigung für das Entfernen der null ist - null ist nur dann gefährlich, wenn sie unsachgemäß verwendet wird, und hat nichts mit "Präzision" zu tun. Der eigentliche Grund, aus dem Sie nicht aus einem Array delete sollten, ist, dass das Ablegen müllgefüllter und unordentlicher Datenstrukturen schlampig und fehleranfällig ist.

Was folgt, ist ein erfundenes Szenario, das ziemlich langwierig wird. Sie können also zum Abschnitt " Die Lösung" springen , wenn Sie möchten. Der einzige Grund, aus dem ich diesen Abschnitt verlasse, ist, dass einige Leute wahrscheinlich denken, dass es lustig ist, und ich möchte nicht "dieser Typ" sein, der eine "lustige" Antwort veröffentlicht und dann später alle "lustigen" Antworten daraus löscht .

... Es ist dumm, ich weiß.

Das konstruierte und langwierige PDP-11-Szenario

Angenommen, Sie erstellen eine Webanwendung, die JSON-Serialisierung verwendet, um ein für 'Tabs' verwendetes Array in einer Zeichenfolge (in diesem Fall localStorage ) zu localStorage . Sagen wir auch, dass der Code die numerischen Indizes der Array-Mitglieder verwendet, um sie beim Zeichnen auf dem Bildschirm zu "benennen". Warum machen Sie das, anstatt nur den "Titel" zu speichern? Weil ... Gründe .

Okay, nehmen wir einfach an, Sie versuchen, Speicher auf Anforderung dieses einen Benutzers zu speichern, der einen PDP-11-Minicomputer aus den 1960er-Jahren unter UNIX ausführt und seinen eigenen Elinks-basierten, JavaScript-kompatiblen, druckerfreundlichen Drucker schreibt Browser, weil X11 nicht in Frage kommt .

In zunehmendem Maße dummes Randfall-Szenario beiseite, führt die Verwendung von delete für das Array dazu, dass das Array mit null verschmutzt wird, was später wahrscheinlich zu Fehlern in der App führt. Wenn Sie nach null suchen, werden die Zahlen direkt übersprungen und die Registerkarten werden wie [1] [2] [4] [5] ... gerendert.

if (array[index] == null)
    continue;
else
    title = (index + 1).toString();
/* 0 -> "1"
 * 1 -> "2"
 * 2 -> (nothing)
 * 3 -> "4"
 */

Ja, das ist definitiv nicht das, was du wolltest.

Jetzt können Sie einen zweiten Iterator wie j beibehalten, der nur dann erhöht wird, wenn gültige Werte aus dem Array gelesen werden. Aber das würde das null Problem nicht genau lösen, und Sie müssen den Troll- PDP-11-Benutzer trotzdem zufriedenstellen . Leider verfügt sein Computer nicht über genügend Speicher für die letzte Ganzzahl (fragen Sie nicht, wie er ein Array mit variabler Breite handhabt ...) .

Also schickt er dir eine Email in Wut:

Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:

>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"

After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!

>var i = index;
>var j = 1;

Grr, I am angry now.
-Troll Davidson

Ungefähr jetzt bist du an deinem Ende. Dieser Typ hat sich ununterbrochen über Ihre App beschwert, und Sie möchten ihm sagen, dass er den Mund halten und einen besseren Computer holen soll.

Die Lösung: Array.prototype.splice

Glücklicherweise verfügen Arrays über eine spezielle Methode zum Löschen von Indizes und zum erneuten Array.prototype.splice() Speicher: Array.prototype.splice() . Sie könnten so etwas schreiben:

Array.prototype.remove = function(index){
  this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]

Und genau so haben Sie Herrn PDP-11 gefallen. Hurra! (Ich würde ihn trotzdem abschrecken ...)

Array.prototype.splice vs Array.prototype.slice

Ich halte es für wichtig, auf den Unterschied zwischen diesen beiden gleichnamigen Funktionen hinzuweisen, da beide sehr nützlich sind.

Array.prototype.splice (Start, n)

.splice() das Array und gibt die entfernten Indizes zurück. Das Array wird beginnend mit dem Index und dem start in Scheiben geschnitten, und n Elemente werden ausgeschnitten. Wenn n nicht angegeben ist, wird das gesamte Array nach dem start herausgeschnitten ( n = array.length - start ).

let a = [5,4,3,2,1];
let chunk = a.splice(2,2);

// a     [5,4,3,2,1]
// start  0 1 2 - -
// n      - - 1 2 -

chunk; // [3,2]
a;     // [5,4,1]

Array.prototype.slice (Start, Ende)

.slice() ist nicht destruktiv und gibt ein neues Array zurück, das die angegebenen Indizes von start bis end . Wenn end nicht angegeben wird, ist das Verhalten dasselbe wie .splice() ( end = array.length ). Das Verhalten ist etwas kompliziert, da aus irgendeinem Grund Indexe von 1 statt von 0 enden. Ich weiß nicht, warum das so ist, aber so ist es. Wenn end <= start , ist das Ergebnis ein leeres Array.

let a = [5,4,3,2,1];
let chunks = [
    a.slice(2,0),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ];

// a             [5,4,3,2,1]
// start          0 1 2 - -
// end, for...    - - - - -
//   chunks[0]  0 - - - - -   
//   chunks[1]    1 2 - - -
//   chunks[2]    1 2 3 - -
//   chunks[3]    1 2 3 4 5

chunks; // [ [], [], [3], [3,2,1] ]
a;      // [5,4,3,2,1]

Das ist eigentlich nicht das, was passiert, aber es ist leichter, so zu denken. Laut MDN ist hier das, was tatsächlich passiert:

// a             [5,4,3,2,1]
// start          0 1 2 - - -
// end, for...    - - - - - -
//   chunks[0]    0 - - - - -
//   chunks[1]    0 1 2 - - -
//   chunks[2]    0 1(2)3 - -
//   chunks[3]    0 1(2 3 4)5

Der durch end angegebene Index wird einfach aus dem Slice ausgeschlossen. Die in Klammern stehenden Indizes geben an, was in Scheiben geschnitten wird. In jedem Fall ist das Verhalten nicht intuitiv und es muss zwangsläufig zu einem beträchtlichen Anteil von Fehlern kommen, so dass Sie eine Wrapper-Funktion .splice() um das Verhalten von .splice() genauer zu emulieren:

function ez_slice(array, start = 0, n = null){
    if(!Array.isArray(array) || !is_number(start))
        return null;

    if(is_number(n))
        return array.slice(start, start + n);

    if(n === null)
        return array.slice(start);

    return null;
}

ez_slice([5,4,3,2,1], 2, 1) // [3]
ez_slice([5,4,3,2,1], 2)    // [3,2,1]

/* Fun fact: isNaN is unreliable.
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(isNaN)
 * [NaN, {}, undefined, "Hi"]
 *
 * What we want is...
 *
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(is_nan)
 * [NaN]
 */
function is_nan(num){
    return typeof num === "number"
        && num !== num;
}

function is_number(num){
    return !is_nan(num)
        && typeof num === "number"
        && isFinite(num);
}

Beachten Sie, dass die Wrapper-Funktion sehr strenge Typen ist und null wenn etwas deaktiviert ist. Dazu gehört das Einfügen einer Zeichenfolge wie "3" . Es bleibt dem Programmierer überlassen, mit seinen Typen fleißig umzugehen. Dies soll gute Programmierpraxis fördern.

Update bezüglich is_array()

Dies ist in Bezug auf dieses (jetzt entfernte) Snippet:

function is_array(array){
    return array !== null
        && typeof array === "object"
        && typeof array.length !== "undefined"
        && array.__proto__ === Array.prototype;
}

Es stellt sich also heraus, dass es tatsächlich eine integrierte Methode gibt, um Array.isArray() , ob ein Array wirklich ein Array ist, und dies ist Array.isArray() , das in ECMAScript 5 (Dezember 2009) eingeführt wurde. Ich fand das, als ich nach einer Frage fragte, ob es darum ging, Arrays von Objekten zu erzählen, ob es entweder eine bessere Lösung als meine gab oder ob ich meine hinzufügen würde, wenn es keine gab. Wenn Sie eine JavaScript-Version verwenden, die älter als ECMA 5 ist, ist Ihre Polyfill-Version verfügbar. Ich empfehle jedoch dringend, meine is_array() Funktion nicht zu verwenden, da die Unterstützung alter JavaScript-Versionen weiterhin die Unterstützung der alten Browser, die diese implementieren, unterstützt. is_array() bedeutet, die Verwendung unsicherer Software zu fördern und die Benutzer für Malware zu gefährden. Verwenden Array.isArray() also bitte Array.isArray() . Verwenden Sie let und const . Verwenden Sie die neuen Funktionen, die der Sprache hinzugefügt werden. Verwenden Sie keine Herstellerpräfixe. Löschen Sie den IE-Polyfill-Mist von Ihrer Website. Löschen Sie das XHTML <!CDATA[[... Mist - wir sind 2014 auf HTML5 umgestiegen. Je früher sich die Unterstützung für diese alten / esoterischen Browser zurückzieht, desto eher werden die Browser-Anbieter dem Webstandard folgen und den Web-Standard umarmen neue Technologie, und desto schneller können wir zu einem sichereren Web übergehen.



2 (ES6)

Für wen auch immer es nötig ist ...

Um die @ Koen-Antwort in diesem Thread zu vervollständigen, können Sie eine dynamische Variable mit der Spread-Syntax entfernen, indem Sie Folgendes tun:

const key = 'a';

const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(rest); // { b: 2, c: 3 }

* fooist eine neue Variable mit dem Wert von a(der 1 ist).


UPDATE :
Es gibt einige Möglichkeiten, eine Eigenschaft aus einem Objekt zu entfernen.
Jeder hat seine Vor- und Nachteile ( siehe Leistungsvergleich ):

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
löschen, lesbar und kurz, es ist jedoch möglicherweise nicht die beste Wahl, wenn Sie mit einer großen Anzahl von Objekten arbeiten, da die Leistung nicht optimiert wird.

delete obj[key];


Reassignment
Mehr als zweimal schneller alsdeletedie Eigenschaft, wird jedochnichtgelöscht und kann wiederholt werden.

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


Spread-Operator Mit
diesemES6Operator können wir ein brandneues Objekt ohne Eigenschaften zurückgeben, ohne das vorhandene Objekt zu verändern. Der Nachteil ist, dass es die schlechtere Leistung hat und nicht empfohlen wird, wenn Sie viele Eigenschaften gleichzeitig entfernen möchten.

{ [key]: val, ...rest } = obj;

Mit ES6:

(Destructuring + Spread-Operator)

    const myObject = {
      regex: "^http://.*",
      b: 2,
      c: 3
    };
    const { regex, ...noRegex } = myObject;
    console.log(noRegex); // => { b: 2, c: 3 }

Dieser Beitrag ist sehr alt und ich finde ihn sehr hilfreich, deshalb habe ich beschlossen, die von mir geschriebene unset-Funktion zu teilen, falls jemand anderes diesen Beitrag sieht und denkt, warum er nicht so einfach ist wie in PHP-unset-Funktion.

Der Grund für das Schreiben dieser neuen unsetFunktion besteht darin, den Index aller anderen Variablen in dieser hash_map beizubehalten. Sehen Sie sich das folgende Beispiel an und sehen Sie, wie sich der Index von "test2" nach dem Entfernen eines Werts aus der Hash_map nicht geändert hat.

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}

Operator delete ist unerwartet langsam!

Schau dir die benchmark .

Löschen ist die einzig wahre Möglichkeit, Objekteigenschaften ohne Reste zu entfernen, aber sie arbeitet ~ 100 Mal langsamer als ihre "Alternative", wobei object[key] = undefined .

Diese Alternative ist nicht die richtige Antwort auf diese Frage! Wenn Sie es jedoch mit Vorsicht verwenden, können Sie einige Algorithmen drastisch beschleunigen. Wenn Sie delete in Schleifen verwenden und Probleme mit der Leistung haben, lesen Sie die ausführliche Erklärung.

Wann sollte man delete und wann den Wert auf undefined ?

Ein Objekt kann als ein Satz von Schlüsselwertpaaren angesehen werden. Was ich einen "Wert" nenne, ist ein Primitiv oder eine Referenz auf ein anderes Objekt, das mit diesem "Schlüssel" verbunden ist.

Verwenden Sie delete , wenn Sie das Ergebnisobjekt an den Code übergeben, auf den Sie keine Kontrolle haben (oder wenn Sie sich nicht sicher sind, ob Ihr Team oder Sie sich sicher sind).

Es löscht den Schlüssel aus der Hashmap .

 var obj = {
     field: 1     
 };
 delete obj.field;

Verwenden Sie die Einstellung zu undefined , wenn Sie Wert auf Leistung legen. Dies kann Ihren Code erheblich verbessern.

Der Schlüssel bleibt an seiner Stelle in der Hashmap , nur der Wert wird durch undefined . Verstehen Sie, dass die for..in Schleife diese Taste noch for..in .

 var obj = {
     field: 1     
 };
 obj.field = undefined;

Bei Verwendung dieser Methode funktionieren nicht alle Möglichkeiten zur Bestimmung der Existenz von Immobilien wie erwartet.

Dieser Code ist jedoch:

object.field === undefined

verhält sich für beide Methoden gleichwertig.

Tests

Zusammenfassend lässt sich for..in , dass es bei den Unterschieden alles um Wege geht, um die Existenz der Eigenschaft zu bestimmen, und etwa for..in Schleife in.

 console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');

 console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');

 console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');

 console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');

 console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');

 console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
 //Object.keys().indexOf() is an overkill that runs much slower :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

Vorsicht vor Speicherlecks!

Während die Verwendung von obj[prop] = undefined schneller ist als das delete obj[prop] , ist eine weitere wichtige Überlegung, dass obj[prop] = undefined nicht immer angemessen ist. delete obj[prop] entfernt die prop aus obj und löscht sie aus dem Gedächtnis, während bei obj[prop] = undefined der Wert von prop einfach auf undefined wodurch die prop noch in Erinnerung bleibt. Unter Umständen, in denen viele Schlüssel erstellt und gelöscht werden, kann die Verwendung von obj[prop] = undefined eine kostspielige Speicherabstimmung (das Einfrieren der Seite) und möglicherweise einen Speicherfehler verursachen. Untersuchen Sie den folgenden Code.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

In dem obigen Code einfach nodeRecords[i][lastTime] = undefined; verursacht einen massiven Speicherverlust, da jeder Animationsframe In jedem Frame werden alle 65536 DOM-Elemente um weitere 65536 einzelne Slots belegt. Die vorherigen 65536-Slots werden jedoch nur auf undefiniert gesetzt, sodass sie im Speicher bleiben. Versuchen Sie, den obigen Code in der Konsole auszuführen, und überzeugen Sie sich selbst. Versuchen Sie nach dem Erzwingen eines Out-of-Memory-Fehlers, diesen erneut auszuführen, außer mit der folgenden Version des Codes, der stattdessen den delete verwendet.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /********************************************/
            /****/ delete nodeRecords[i][lastTime]; /****/
            /********************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

Wie im obigen Code-Snippet zu sehen, gibt es einige selten geeignete Anwendungsfälle für den delete . Sorgen Sie sich jedoch nicht zu sehr um dieses Problem. Dies wird nur bei Objekten mit langer Lebensdauer zu einem Problem, bei denen ständig neue Schlüssel hinzugefügt werden. In jedem anderen Fall (was in der realen Programmierung fast immer der Fall ist), ist es am besten, obj[prop] = undefined . Der Hauptzweck dieses Abschnitts besteht darin, Sie darauf aufmerksam zu machen, so dass Sie in der seltenen Gelegenheit, dass dies zu einem Problem in Ihrem Code wird, das Problem leichter verstehen können und somit keine Stunden damit verbringen müssen, Ihren Code zu lokalisieren und verstehen dieses Problem.

Nicht immer auf undefined

Ein wichtiger Aspekt von Javascript ist der Polymorphismus. Polymorphismus ist, wenn verschiedene Variablen / Slot-in-An-Objekte zugewiesen werden, wie im Folgenden dargestellt.

var foo = "str";
foo = 100;          // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text";    // bar is a monomorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array

Bei polymorphen Arrays gibt es jedoch zwei große, nicht zu lösende Probleme:

  1. Sie sind langsam und das Gedächtnis ineffizient. Beim Zugriff auf einen bestimmten Index muss der Browser nicht nur den globalen Typ für das Array abrufen, sondern den Typ auf Indexbasis, wobei jeder Index die zusätzlichen Metadaten seines Typs speichert.
  2. Einmal polymorph, immer polymorph. Wenn ein Array polymorph gemacht wird, kann der Polymorphismus in Webkit-Browsern nicht rückgängig gemacht werden. Selbst wenn Sie also ein polymorphes Array als nicht-polymorph anzeigen, wird es vom Browser immer noch als polymorphes Array gespeichert.

Man kann Polymorphismus mit einer Drogensucht vergleichen. Auf den ersten Blick erscheint es unglaublich lukrativ: schöner, flockiger Code. Dann führt der Kodierer sein Array in das Medikament des Polymorphismus ein. Sofort wird das polymorphe Array weniger effizient und kann nie so effizient werden wie zuvor, da es mit Drogen behandelt wird. Um einen solchen Umstand mit dem wirklichen Leben in Beziehung zu setzen, könnte jemand, der Kokain konsumiert, möglicherweise nicht einmal einen einfachen Türgriff betätigen, geschweige denn die PI-Ziffern berechnen. Ebenso kann ein Array auf dem Wirkstoff Polymorphismus niemals so effizient sein wie ein monomorphes Array.

Aber wie verhält sich eine Analogie zur Drogenreise mit der delete ? Die Antwort übernimmt die letzte Codezeile in dem obigen Snippet. Lassen Sie es also noch einmal prüfen, diesmal mit einer Wendung.

var bar = ["Some", "example"];
bar[2] = "text";    // bar is not a polymorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = "";        // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array

Beobachten. bar[1] = "" erzwingt keinen Polymorphismus, während bar[1] = undefined ist. Daher sollte man immer, wenn möglich, den entsprechenden Typ für ihre Objekte verwenden, um nicht versehentlich Polymorphismus zu verursachen. Eine solche Person kann die folgende Liste als allgemeine Referenz verwenden, um sie in Gang zu setzen. Bitte verwenden Sie die nachstehenden Ideen jedoch nicht explizit. Verwenden Sie stattdessen das, was für Ihren Code gut geeignet ist.

  • Wenn Sie ein Array / eine Variable verwenden, die für das boolesche Grundelement typisiert ist, verwenden Sie entweder false oder undefined als leeren Wert. Das Vermeiden von unnötigem Polymorphismus ist zwar gut, aber das erneute Schreiben des gesamten Codes, um explizit zu verbieten, führt wahrscheinlich zu einem Leistungsabfall. Verwenden Sie ein gemeinsames Urteil!
  • Wenn Sie ein Array / eine Variable verwenden, die für das Zahlenprimitiv eingegeben wurde, verwenden Sie 0 als leeren Wert. Beachten Sie, dass es intern zwei Arten von Zahlen gibt: schnelle Ganzzahlen (einschließlich 2147483647 bis einschließlich -2147483648) und langsame Fließkomma-Doubles (andere Werte als die von NaN und Infinity ). Wenn eine Ganzzahl zu einem Double herabgestuft wird, kann sie nicht zu einer Ganzzahl zurückgestuft werden.
  • Wenn Sie ein Array / eine Variable verwenden, die für das String-Grundelement typisiert ist, verwenden Sie "" als leeren Wert.
  • Wenn Sie ein Symbol verwenden, warten Sie, warum verwenden Sie ein Symbol?!?! Symbole sind schlechte Juju für Leistung. Alles, das für die Verwendung von Symbolen programmiert wurde, kann neu programmiert werden, um keine Symbole zu verwenden. Dies führt zu einem schnelleren Code ohne Symbole. Symbole sind wirklich nur super ineffizienter Metazucker.
  • Wenn Sie etwas anderes verwenden, verwenden Sie null .

Seien Sie jedoch vorsichtig! Fangen Sie jetzt nicht plötzlich mit Ihrem gesamten vorhandenen Code an, da dieser Code möglicherweise beschädigt wird und / oder seltsame Fehler auftreten. Vielmehr muss eine solche effiziente Vorgehensweise von Anfang an implementiert werden. Beim Konvertieren von bereits vorhandenem Code wird empfohlen, dass Sie alle Zeilen, die sich darauf beziehen, doppelt, dreifach und vierfach prüfen, da der Versuch unternommen werden kann, alten Code auf diese neue Vorgehensweise umzustellen riskant wie es lohnend ist.


var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
    
delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

Dies funktioniert in Firefox und Internet Explorer, und ich denke, es funktioniert in allen anderen.


Erstellen Sie ein neues Objekt ohne die "regex"Eigenschaft, da das Originalobjekt immer von anderen Programmteilen referenziert werden kann. Daher sollten Sie es vermeiden, es zu manipulieren.

const myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

const { regex, ...newMyObject } = myObject;

console.log(newMyObject);


Versuche dies

delete myObject['key'];

Mit ramda#dissoc Sie ein neues Objekt ohne das Attribut regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

Sie können auch andere Funktionen verwenden, um denselben Effekt zu erzielen - Auslassen, Auswählen, ...


Eine andere Alternative ist die Verwendung der Underscore.js- Bibliothek.

Beachten Sie, dass _.pick() und _.omit() beide eine Kopie des Objekts zurückgeben und das ursprüngliche Objekt nicht direkt ändern. Das Zuweisen des Ergebnisses zu dem ursprünglichen Objekt sollte den Trick ausführen (nicht gezeigt).

Referenz: link _.pick (Objekt, * Schlüssel)

Gibt eine Kopie des Objekts zurück, die so gefiltert ist, dass sie nur Werte für die auf der Whitelist aufgeführten Schlüssel (oder das Array gültiger Schlüssel) enthält.

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

Referenz: link _.omit (Objekt, * Schlüssel)

Gibt eine Kopie des Objekts zurück, gefiltert, um die auf der schwarzen Liste aufgelisteten Schlüssel (oder das Array von Schlüsseln) wegzulassen.

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

Für Arrays können _.filter() und _.reject() auf ähnliche Weise verwendet werden.


Sie können einfach jede Eigenschaft eines Objekts mit dem deleteSchlüsselwort löschen .

Zum Beispiel:

var obj = {key1:"val1",key2:"val2",key3:"val3"}

Um beispielsweise eine Eigenschaft zu entfernen key1, verwenden Sie das deleteSchlüsselwort wie folgt:

delete obj.key1

Oder Sie können auch eine Array-ähnliche Notation verwenden:

delete obj[key1]

Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .


Sehr einfach:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

delete myObject.regex;

Lodash benutzen

import omit from 'lodash/omit';

const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');

Ramda verwenden

R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}

Ich persönlich benutze Underscore.js für die Objekt- und Array-Manipulation:

myObject = _.omit(myObject, 'regex');

Es gibt viele gute Antworten, aber ich möchte nur darauf hinweisen, dass bei der Verwendung von delete zum Entfernen einer Eigenschaft in JavaScript häufig zuerst geprüft wird, ob diese Eigenschaft vorhanden ist, um Fehler zu vermeiden.

Z.B

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}

Aufgrund der dynamischen Natur von JavaScript gibt es oft Fälle, in denen Sie einfach nicht wissen, ob die Eigenschaft existiert oder nicht. Wenn Sie prüfen, ob obj vor dem && vorhanden ist, wird auch sichergestellt, dass Sie keinen Fehler aufgrund des Aufrufs der Funktion hasOwnProperty () für ein undefiniertes Objekt auslösen.

Es tut uns leid, wenn dies nicht zu Ihrem speziellen Anwendungsfall beigetragen hat, aber ich denke, dass dies ein gutes Design ist, das bei der Verwaltung von Objekten und deren Eigenschaften angepasst werden muss.


Eigenschaftsentfernung in JavaScript

Es gibt viele verschiedene Optionen auf dieser Seite, nicht weil die meisten Optionen falsch sind - oder weil die Antworten Duplikate sind -, sondern weil die geeignete Technik von der Situation abhängt, in der Sie sich befinden, und den Zielen der Aufgaben, die Sie und / oder Sie stellen Team versucht zu erfüllen. Um Ihre Frage eindeutig zu beantworten, muss man wissen:

  1. Die Version von ECMAScript, auf die Sie abzielen
  2. Der Bereich der Objekttypen, für den Sie die Eigenschaften entfernen möchten, und der Typ der Eigenschaftsnamen, die Sie weglassen müssen (nur Strings? Symbole? Schwache Referenzen, die von beliebigen Objekten zugeordnet werden.) Dies sind seit Jahren Typen von Eigenschaftszeigern in JavaScript )
  3. Die Programmierethos / -muster, die Sie und Ihr Team verwenden. Bevorzugen Sie funktionale Ansätze und Mutationen sind in Ihrem Team verboten, oder wenden Sie objektorientierte Wild-West-Mutationstechniken an?
  4. Möchten Sie dies mit reinem JavaScript erreichen oder möchten Sie eine Drittanbieter-Bibliothek verwenden?

Sobald diese vier Fragen beantwortet wurden, gibt es im Wesentlichen vier Kategorien für das Entfernen von Eigenschaften in JavaScript, aus denen Sie auswählen können, um Ihre Ziele zu erreichen. Sie sind:

Löschen von mutativen Objekteigenschaften, unsicher

Diese Kategorie ist für die Bearbeitung von Objektliteralen oder Objektinstanzen gedacht, wenn Sie die ursprüngliche Referenz beibehalten oder weiterhin verwenden möchten und keine statusfreien Funktionsprinzipien in Ihrem Code verwenden. Ein Beispiel für eine Syntax in dieser Kategorie:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws

Diese Kategorie ist die älteste, unkomplizierteste und am meisten unterstützte Kategorie der Entfernung von Immobilien. Es unterstützt Symbolzusätzlich zu Strings & Array-Indizes und funktioniert mit Ausnahme der ersten Version in jeder Version von JavaScript. Es ist jedoch mutativ, was einige Programmierprinzipien verletzt und Auswirkungen auf die Leistung hat. Es kann auch zu developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… erfassten Ausnahmen führen, wenn sie für developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .

Rest-basierte String-Eigenschaftsauslassung

Diese Kategorie ist für den Betrieb mit einfachen Objekt- oder Arrayinstanzen in neueren ECMAScript-Varianten vorgesehen, wenn ein nicht mutativer Ansatz gewünscht wird und Sie keine Symboltasten berücksichtigen müssen:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

Löschen mutativer Objekteigenschaften, sicher

Diese Kategorie ist für die Bearbeitung von Objektliteralen oder Objektinstanzen gedacht, wenn Sie die ursprüngliche Referenz beibehalten oder weiterhin verwenden möchten, während Sie verhindern, dass Ausnahmen für nicht konfigurierbare Eigenschaften ausgelöst werden:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

Während das Mutieren von Objekten an Ort und Stelle nicht zustandslos ist, können Sie die funktionale Natur von Reflect.deletePropertyPartial Application und andere funktionale Techniken verwenden, die mit deleteAnweisungen nicht möglich sind .

Syntaxbasierte Auslassung von String-Eigenschaften

Diese Kategorie ist für den Betrieb mit einfachen Objekt- oder Arrayinstanzen in neueren ECMAScript-Varianten vorgesehen, wenn ein nicht mutativer Ansatz gewünscht wird und Sie keine Symboltasten berücksichtigen müssen:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

Bibliotheksbasierte Auslassung von Eigenschaften

Diese Kategorie ermöglicht im Allgemeinen eine größere Funktionsflexibilität, einschließlich der Berücksichtigung von Symbolen und dem Weglassen mehrerer Eigenschaften in einer Anweisung:

const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"

Hallo, du kannst diese einfache Art ausprobieren

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);

Stringify löst nicht alle Probleme

Es scheint, dass die Antworten hier nicht alle Arten abdecken, die in JavaScript möglich sind, daher hier einige kurze Beispiele für den richtigen Umgang mit ihnen:

//Objects and Arrays:
    var obj = {key: "value"};
    localStorage.object = JSON.stringify(obj);  //Will ignore private members
    obj = JSON.parse(localStorage.object);
//Boolean:
    var bool = false;
    localStorage.bool = bool;
    bool = (localStorage.bool === "true");
//Numbers:
    var num = 42;
    localStorage.num = num;
    num = +localStorage.num;    //short for "num = parseFloat(localStorage.num);"
//Dates:
    var date = Date.now();
    localStorage.date = date;
    date = new Date(parseInt(localStorage.date));
//Regular expressions:
    var regex = /^No\.[\d]*$/i;     //usage example: "No.42".match(regex);
    localStorage.regex = regex;
    var components = localStorage.regex.match("^/(.*)/([a-z]*)$");
    regex = new RegExp(components[1], components[2]);
//Functions (not recommended):
    function func(){}
    localStorage.func = func;
    eval( localStorage.func );      //recreates the function with the name "func"

Ich empfehle das Speichern von Funktionen nicht, da eval() böse ist und zu Problemen in Bezug auf Sicherheit, Optimierung und Debugging führen kann. Im Allgemeinen sollte eval() niemals in JavaScript-Code verwendet werden.

Private Mitglieder

Das Problem bei der Verwendung von JSON.stringify() zum Speichern von Objekten besteht darin, dass diese Funktion private Member nicht serialisieren kann. Dieses Problem kann durch Überschreiben der .toString() -Methode (die beim Speichern von Daten im .toString() implizit .toString() gelöst werden:

//Object with private and public members:
    function MyClass(privateContent, publicContent){
        var privateMember = privateContent || "defaultPrivateValue";
        this.publicMember = publicContent  || "defaultPublicValue";

        this.toString = function(){
            return '{"private": "' + privateMember + '", "public": "' + this.publicMember + '"}';
        };
    }
    MyClass.fromString = function(serialisedString){
        var properties = JSON.parse(serialisedString || "{}");
        return new MyClass( properties.private, properties.public );
    };
//Storing:
    var obj = new MyClass("invisible", "visible");
    localStorage.object = obj;
//Loading:
    obj = MyClass.fromString(localStorage.object);

Zirkelverweise

Ein weiteres Problem, mit dem stringify nicht umgehen kann, sind stringify :

var obj = {};
obj["circular"] = obj;
localStorage.object = JSON.stringify(obj);  //Fails

In diesem Beispiel JSON.stringify() einen TypeError "Konvertieren einer zirkularen Struktur in JSON" . Wenn das Speichern von JSON.stringify() unterstützt werden soll, kann der zweite Parameter von JSON.stringify() verwendet werden:

var obj = {id: 1, sub: {}};
obj.sub["circular"] = obj;
localStorage.object = JSON.stringify( obj, function( key, value) {
    if( key == 'circular') {
        return "$ref"+value.id+"$";
    } else {
        return value;
    }
});

Die Suche nach einer effizienten Lösung zum Speichern von Zirkelreferenzen hängt jedoch in hohem Maße von den Aufgaben ab, die gelöst werden müssen. Auch das Wiederherstellen solcher Daten ist nicht trivial.

Es gibt bereits einige Fragen zu SO, die sich mit diesem Problem befassen : Stringify (in JSON konvertieren) ein JavaScript-Objekt mit Zirkelreferenz





javascript javascript-objects object-properties