Wie entferne ich eine Eigenschaft aus einem JavaScript-Objekt?


6141

Angenommen, ich erstelle ein Objekt wie folgt:

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

Was ist der beste Weg , um die Eigenschaft zu entfernen , regexum am Ende mit neuem myObjectwie folgt?

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


@EscapeNetscape Dies ist eine Frage zum Verhalten, daher zeichnet ein Benchmark das falsche Bild. Natürlich deletewäre dies die langsamste Option, da es sich eher um eine tatsächliche Operation als um die beiden anderen handelt, bei denen es sich nur um einfache Zuweisungen handelt. Der springende Punkt ist jedoch, dass das Zuweisen der Eigenschaft zum Objekt nulloder undefineddas Entfernen der Eigenschaft aus dem Objekt tatsächlich entfernt wird, sondern diese Eigenschaft auf einen bestimmten konstanten Wert gesetzt wird. (Die folgenden Antworten geben Gründe an, warum dies ein signifikanter Unterschied ist.)
Abion47

Antworten:


8304

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 lesen möchten, hat der Stack Overflow-Benutzer kangax einen unglaublich ausführlichen Blog-Beitrag über die deleteAussage in seinem Blog " Löschen verstehen" geschrieben . Es wird dringend empfohlen.


47
Aktiviert funktioniert es auch mit "delete myJSONObject ['regex'];" Siehe: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok

110
Ein Ergebnis einer der Beobachtungen unter dem obigen Link "Verständnis löschen" ist, dass Sie, da Sie nicht unbedingt eine Variable, sondern nur Objekteigenschaften löschen können, eine Objekteigenschaft daher nicht "durch Bezugnahme" löschen können - var value = obj [ 'Stütze']; Wert löschen // funktioniert nicht
Dexygen

27
Also wird es nicht wirklich gelöscht? Es wird nur undefiniert, aber der Schlüssel existiert noch? Vermisse ich etwas
Doug Molineux

152
@Pete nein, es entfernt es. Gegeben: var x = {a : 'A', b : 'B'};Vergleiche: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */tox.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf

16
@ChristopherPfohl arbeitet für mich. Wie ich schon sagte, es ist eigentlich ziemlich ausführlich, also ist es ein bisschen schwierig zusammenzufassen. Die grundlegende Antwort in der obigen Antwort ist für fast alle Fälle ausreichend. Der Blog befasst sich mit einigen weiteren Randfällen und den Gründen, aus denen diese Fälle existieren.
Nickf

952

Objekte in JavaScript können als Zuordnungen zwischen Schlüsseln und Werten betrachtet werden. Der deleteOperator wird verwendet, um diese Schlüssel, die allgemein als Objekteigenschaften bezeichnet werden, einzeln zu entfernen.

var obj = {
  myProperty: 1    
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false

Der deleteBetreiber nicht direkt freier Speicher, und es unterscheidet sich von einfach den Wert der Zuweisung nulloder undefinedeiner Eigenschaft, dass die Eigenschaft sich von dem Objekt entfernt wird. Beachten Sie, dass, wenn der Wert einer gelöschten Eigenschaft ein Referenztyp (ein Objekt) war und ein anderer Teil Ihres Programms noch einen Verweis auf dieses Objekt enthält, dieses Objekt natürlich erst dann mit Müll belegt wird, wenn alle Verweise darauf vorhanden sind verschwunden.

delete funktioniert nur für Eigenschaften, deren Deskriptor sie als konfigurierbar markiert.


43
Eine Eigenschaft, die undefiniert zugewiesen ist, ist immer noch eine Eigenschaft eines Objekts. Sie wird daher von GC nicht entfernt, es sei denn, Sie haben Ihren letzten Absatz falsch gelesen.
Lance

8
Ich habe mich geirrt, hier das Thema GC anzusprechen. Beide Methoden haben für GC das gleiche Ergebnis: Sie entfernen den mit dem Schlüssel verknüpften Wert. Wenn dieser Wert der letzte Verweis auf ein anderes Objekt wäre, würde dieses Objekt bereinigt.
Dan

15
Eine Eigenschaft, die undefiniert zugewiesen ist, ist immer noch eine Eigenschaft eines Objekts, sodass sie vom GC nicht entfernt wird. Der GC verwaltet nichts über Eigenschaften. Es sammelt und entfernt Werte. Solange nichts mehr auf einen Wert (ein Objekt, eine Zeichenfolge usw.) verweist, entfernt der GC ihn aus dem Speicher.
Meandre

8
Übrigens, das ist das doppelte Problem, um zu überprüfen, ob eine Eigenschaft für ein Javascript-Objekt vorhanden ist. Die Verwendung im Bediener ist zuverlässig, aber langsam. Überprüfen Sie, ob die Eigenschaft nicht undefiniert ist "ist nicht die richtige Antwort", aber es ist viel schneller. check
rdllopes

8
Ist diese Antwort noch relevant? jsperf ist derzeit nicht verfügbar, aber dieser Benchmark scheint darauf hinzudeuten, dass der Geschwindigkeitsunterschied lediglich 25% beträgt, was bei weitem nicht annähernd dem "~ 100-mal langsameren" Wert in dieser Antwort entspricht.
Cerbrus

248

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.


216

Der deleteOperator wird verwendet, um Eigenschaften von Objekten zu entfernen.

const obj = { foo: "bar" }
delete obj.foo
obj.hasOwnProperty("foo") // false

Beachten Sie, dass dies für Arrays nicht mit dem Entfernen eines Elements identisch ist . Verwenden Sie Array#spliceoder, um ein Element aus einem Array zu entfernen Array#pop. Zum Beispiel:

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

Einzelheiten

deletein JavaScript hat eine andere Funktion als das Schlüsselwort in C und C ++: Es gibt keinen direkten Speicher frei. Stattdessen besteht der einzige Zweck darin, Eigenschaften von Objekten zu entfernen.

Wenn Sie für Arrays eine Eigenschaft löschen, die einem Index entspricht, wird ein Array mit geringer Dichte erstellt (dh ein Array mit einem "Loch" darin). Die meisten Browser stellen diese fehlenden Array-Indizes als "leer" dar.

var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]

Beachten Sie, dass deletenicht in verlagert array[3]wird array[2].

Verschiedene in JavaScript integrierte Funktionen behandeln spärliche Arrays unterschiedlich.

  • for...in überspringt den leeren Index vollständig.

  • Eine herkömmliche forSchleife gibt undefinedden Wert am Index zurück.

  • Jede verwendete Methode Symbol.iteratorgibt undefinedden Wert am Index zurück.

  • forEach, mapUnd reducewird einfach die fehlenden Index überspringen.

Daher sollte der deleteOperator nicht für den allgemeinen Anwendungsfall des Entfernens von Elementen aus einem Array verwendet werden. Arrays verfügen über spezielle Methoden zum Entfernen von Elementen und zum Neuzuweisen von Speicher: Array#splice()und Array#pop.

Array # splice (start [, deleteCount [, item1 [, item2 [, ...]]])

Array#splicemutiert das Array und gibt alle entfernten Indizes zurück. deleteCountElemente werden aus dem Index entfernt start, und item1, item2... itemNwerden in das Array von Index eingefügt start. Wenn nicht deleteCountangegeben, werden Elemente aus startIndex bis zum Ende des Arrays entfernt.

let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]

Es gibt auch eine ähnlich benannte, aber unterschiedliche Funktion für Array.prototype: Array#slice.

Array # Slice ([Anfang [, Ende]])

Array#sliceist zerstörungsfrei und gibt ein neues Array zurück, das die angegebenen Indizes von startbis enthält end. Wenn endnicht angegeben, wird standardmäßig das Ende des Arrays verwendet. Wenn dies endpositiv ist, wird der auf Null basierende nicht inklusive Index angegeben, bei dem gestoppt werden soll. Wenn endes negativ ist, gibt es den Index an, bei dem angehalten werden soll, indem vom Ende des Arrays zurückgezählt wird (z. B. wird -1 den endgültigen Index weglassen). Wenn end <= start, ist das Ergebnis ein leeres Array.

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

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

Array # pop

Array#popEntfernt das letzte Element aus einem Array und gibt dieses Element zurück. Diese Operation ändert die Länge des Arrays.


12
Dieser Ansatz ändert nicht das ursprüngliche Objekt, auf das möglicherweise noch an anderer Stelle verwiesen wird. Dies kann ein Problem sein oder auch nicht, je nachdem, wie es verwendet wird, aber es ist etwas zu beachten.
Tamas Czinege

19
@ B1KMusic Hier ist der Weg, um ein Element aus einem Array zu löschen: Splice
Wulftone

3
@wulftone nein, das teilt das Array und tut nichts, um einen Wert zu löschen. Ich denke wirklich, dass der beste Weg, um aus einem Array zu löschen, in dem bestimmte Werte gelöscht werden müssen, darin besteht delete, eine Garbage Collection-Funktion zu verwenden und zu erstellen, um es zu bereinigen.
Braden Best

5
Ich sehe nicht splicein Ihrer Bearbeitung, removesollte aber seinArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-

1
Dieser Artikel ist voller Bullen 1. Er geht nicht auf die Frage ein! 2. Es ist ein beispielhafter Missbrauch der Sprache und eine Beschwerde darüber, dass "es nicht funktioniert!" 3. Machen Sie den JavaScript- Löschoperator nicht für Crockfords eigenwilligen Fehler verantwortlich, Null für einen leeren Array-Index zu setzen. Er versteht die Bedeutung von Null nicht - er hält es für einen Fehler. Der Fehler ist sein eigener und alleiniger - der gelöschte Wert eines bestimmten Array-Index enthält keine Null. Es gibt kein "Loch" im Array - das ist ein leerer Index. Absolut legitim und erwartet.
Bekim Bacaj

195

Alte Frage, moderne Antwort. Mit der Objektdestrukturierung, einer ECMAScript 6- Funktion, ist dies so einfach wie:

const { a, ...rest } = { a: 1, b: 2, c: 3 };

Oder mit dem Fragenbeispiel:

const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);

Sie können es im Babel-Testeditor in Aktion sehen.


Bearbeiten:

Verwenden Sie a, um dieselbe Variable neu zuzuweisen let:

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);

6
Vielleicht, weil das Ziel darin besteht, eine Eigenschaft aus einem Objekt zu entfernen und keine neue ohne die Eigenschaft zu erstellen ... obwohl Ihre Lösung meine Lieblingslösung ist, da ich den unveränderlichen Weg bevorzuge.
Vingt_centimes

8
Die Frage lautete " um mit neuem myObject zu enden".
Koen.

1
Das Hinzufügen eines Unterstrichs zum Entfernen einer Eigenschaft verschmutzt Ihr Projekt :) Anstatt es verfügbar zu haben, können regexSie es auch einer anderen Variablen zuweisen, z. B. _was in Sprachen wie Go verwendet wird, um ein Ergebnis zu verwerfen : const { regex: _, ...newObject } = myObject;.
Koen.

2
@PranayKumar Ich hatte gehofft, dass diese Syntax funktionieren würde; const { [key], ...newObject } = myObject;aber das tut es nicht, also denke ich nicht, dass es mit Destrukturierung möglich ist.
Koen.

2
Mit freeze()'d und seal()' d Objekten können Sie nicht einfach deleteeine Eigenschaft. Das ist also eine ausgezeichnete Alternative. Obwohl es in den meisten Fällen wahrscheinlich nicht sinnvoll ist, eine Eigenschaft aus einem eingefrorenen / versiegelten Objekt zu löschen, ist es wichtig, bestimmte Garantien für Ihre Datenstrukturen zu geben, die dieses Muster untergraben würden. Für die Fälle, in denen Sie ein Objekt zerstörungsfrei betrügen müssen, aber ohne einige seiner Eigenschaften, ist dies perfekt
Braden Best

118

Spread-Syntax (ES6)

Wer es braucht ...

Um die @ Ken-Antwort in diesem Thread zu vervollständigen, können Sie die folgenden Variablen wie folgt entfernen: Wenn Sie dynamische Variablen mithilfe der Spread-Syntax entfernen möchten:

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

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

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


ERWEITERTE ANTWORT 😇
Es gibt nur wenige Möglichkeiten, eine Eigenschaft aus einem Objekt zu entfernen.
Jeder hat seine eigenen Vor- und Nachteile ( überprüfen Sie diesen Leistungsvergleich ):

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

delete obj[key];


Neuzuweisung
Mehr als 2X schneller alsdelete, die 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 mutieren. Der Nachteil ist, dass es die schlechtere Leistung als oben beschrieben aufweist und nicht empfohlen wird, wenn Sie viele Eigenschaften gleichzeitig entfernen müssen.

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

2
Ich denke, die Spread / Rest-Syntax für Objektliterale war nur in ES2018 (ES9) enthalten, nicht in ES6, obwohl mehrere JS-Engines sie bereits implementiert hatten.
Trincot

2
@trincot Es wurde erstmals 2014 eingeführt ( github.com/tc39/proposal-object-rest-spread ) und ist eine ES6-Funktion (ECMAScript 2015, auch bekannt als ECMAScript 6th Edition). Selbst wenn ich mich irre, glaube ich nicht, dass dies den Kontext der Antwort beeinflusst.
Lior Elrom

2
Der Link bezieht sich auf ES6, wo zwar die Spread-Syntax für Arrays eingeführt wurde, dann aber weiterhin etwas Ähnliches für Objektliterale vorgeschlagen wird. Dieser zweite Teil wurde nur in ES9 aufgenommen, wenn ich mich nicht irre.
Trincot

98

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

Beachten Sie, dass _.pick()und _.omit()beide Rückkehr einer Kopie des Objekts und nicht direkt das ursprüngliche Objekt ändern. Das Zuweisen des Ergebnisses zum ursprünglichen Objekt sollte den Trick ausführen (nicht gezeigt).

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

Geben Sie eine Kopie des Objekts zurück, die so gefiltert ist, dass sie nur Werte für die Whitelist-Schlüssel (oder ein 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)

Geben Sie eine Kopie des Objekts zurück, die gefiltert wurde, um die Schlüssel auf der schwarzen Liste (oder ein Array von Schlüsseln) wegzulassen.

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

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

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


4
Denken Sie daran, wenn die Schlüssel Ihres Objekts Zahlen sind, müssen Sie möglicherweise_.omit(collection, key.toString())
Jordan Arseno

Hmmmmm .... Unterstrich ist ~ 100x langsamer als delete obj[prop]~ 100x langsamer als obj[prop] = undefined.
Jack Giffin

52

Der Begriff, den Sie in Ihrem Fragentitel verwendet haben Remove a property from a JavaScript object, kann auf verschiedene Arten interpretiert werden. Das eine ist, es für den gesamten Speicher zu entfernen und die Liste der Objektschlüssel oder das andere ist nur, es von Ihrem Objekt zu entfernen. Wie bereits in einigen anderen Antworten erwähnt, ist das deleteSchlüsselwort der Hauptteil. Angenommen, Sie haben Ihr Objekt wie folgt:

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 für den Speicher interessieren und das gesamte Objekt aus dem Speicher entfernen möchten, wird empfohlen, es vor dem Löschen des Schlüssels auf null zu setzen:

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

Der andere wichtige Punkt hier ist, vorsichtig mit Ihren anderen Verweisen auf dasselbe Objekt umzugehen. 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, wie:

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

Dann auch, wenn Sie es von Ihrem Objekt entfernen myJSONObject , wird dieses bestimmte Objekt nicht aus dem Speicher gelöscht, da die regexVariable myOtherObject["regex"]immer noch ihre Werte hat. Wie können wir dann das Objekt sicher aus dem Speicher entfernen?

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

In diesem Fall können Sie dieses Objekt nicht entfernen, da Sie die regexVariable über eine varAnweisung erstellt haben. Wenn Sie dies tun:

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 noch nicht erstellt hätten und sie nur myOtherObject["regex"]als letzte vorhandene Referenz verwendet hätten, hätten Sie dies einfach tun können, indem Sie sie wie folgt entfernen:

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

Mit anderen Worten, ein JavaScript-Objekt wird getötet, sobald in Ihrem Code kein Verweis mehr auf dieses Objekt vorhanden ist.


Aktualisieren: Danke an @AgentME:

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

Weitere Informationen zu Object.seal: Object.seal ()


Sie liegen falsch - nur Objekte werden in JavaScript als Referenz übergeben. Wenn myJSONObject.regexder Wert also eine Zeichenfolge ist und Sie ihn einem anderen Objekt zuweisen, verfügt das andere Objekt über eine Kopie dieses Werts.
Michał Perłakowski

Sie haben Recht und dies ist ein Zitat: "Seien Sie vorsichtig mit Ihren anderen Verweisen auf dasselbe Objekt."
Mehran Hatami

43

ECMAScript 2015 (oder ES6) wurde mit einem integrierten Reflect- Objekt geliefert . Sie können die Objekteigenschaft löschen, indem Sie die Funktion Reflect.deleteProperty () mit dem Zielobjekt und dem Eigenschaftsschlüssel als Parametern aufrufen :

Reflect.deleteProperty(myJSONObject, 'regex');

was äquivalent ist zu:

delete myJSONObject['regex'];

Wenn die Eigenschaft des Objekts jedoch nicht konfigurierbar ist, kann sie weder mit der Funktion deleteProperty noch mit dem Löschoperator gelöscht werden:

let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value

Object.freeze () macht alle Eigenschaften des Objekts (neben anderen Dingen) nicht konfigurierbar. deletePropertyDie Funktion (sowie der Löschoperator ) wird zurückgegeben, falsewenn versucht wird, eine ihrer Eigenschaften zu löschen. Wenn die Eigenschaft konfigurierbar ist, wird sie zurückgegeben true, auch wenn die Eigenschaft nicht vorhanden ist.

Der Unterschied zwischen deleteund deletePropertybesteht bei Verwendung des strengen Modus:

"use strict";

let obj = Object.freeze({ prop: "value" });
Reflect.deleteProperty(obj, "prop"); // false
delete obj["prop"];
// TypeError: property "prop" is non-configurable and can't be deleted

1
@ Gothdo hat mehr Vorteile, besonders wenn Sie einige funktionale Dinge tun müssen. Zum Beispiel können Sie Funktion auf Variable, übergeben Sie als Argument oder Verwendung zuweisen apply, call, bindFunktionen ...
madox2

41

Angenommen, Sie haben ein Objekt, das so aussieht:

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

Löschen einer Objekteigenschaft

Wenn Sie das gesamte staffArray verwenden möchten , ist dies der richtige Weg:

delete Hogwarts.staff;

Alternativ können Sie auch Folgendes tun:

delete Hogwarts['staff'];

In ähnlicher Weise würde das Entfernen des gesamten Schülerarrays durch Aufrufen von delete Hogwarts.students;oder erfolgendelete Hogwarts['students']; .

Löschen eines Array-Index

Wenn Sie nun einen einzelnen Mitarbeiter oder Schüler entfernen möchten, ist die Vorgehensweise etwas anders, da beide Eigenschaften selbst Arrays sind.

Wenn Sie den Index Ihres Mitarbeiters kennen, können Sie dies einfach tun:

Hogwarts.staff.splice(3, 1);

Wenn Sie den Index nicht kennen, müssen Sie auch eine Indexsuche durchführen:

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

Hinweis

Während Sie es technisch deletefür ein Array verwenden können, würde die Verwendung dieses Arrays zu falschen Ergebnissen führen, wenn Sie beispielsweise Hogwarts.staff.lengthspäter aufrufen . Mit anderen Worten, deletewürde das Element entfernen, aber den Wert der lengthEigenschaft nicht aktualisieren . Die Verwendung deletewürde auch Ihre Indizierung durcheinander bringen.

Überlegen Sie beim Löschen von Werten aus einem Objekt immer zuerst, ob es sich um Objekteigenschaften oder um Array-Werte handelt, und wählen Sie darauf basierend die entsprechende Strategie aus.

Wenn Sie damit experimentieren möchten, können Sie diese Geige als Ausgangspunkt verwenden.


Ich würde denken, Sie sollten immer spliceauf einem Array anstelle von verwenden delete.
Joel Trauger

@ JoelTrauger: Das sage ich ;-)
John Slegers

Ja. Mein Kommentar ist, dass deletedas nicht einmal eine Sache sein sollte. Es spliceist das, wonach das OP gesucht hat.
Joel Trauger

1
@JoelTrauger: Wie ich zu erklären versuchte, deletesollte für Objekteigenschaften und splicefür Array-Elemente verwendet werden.
John Slegers

Spleißen ist sehr langsam. Während es anstelle von deleteArrays verwendet werden sollte, wäre es am klügsten, überhaupt keinen Code zu erstellen, der darauf zentriert ist.
Jack Giffin

39

Verwenden von ES6:

(Destructuring + Spread Operator)

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

Ich denke nicht, dass dies eine ES6-Funktion ist, sondern eine, die nur in ES9 enthalten war.
Trincot

Also benutzt du eigentlich nicht ES6, wie du schreibst, sondern ES9 ... ;-)
Trincot

2
Dies entfernt keine Eigenschaft aus einem Objekt, sondern erstellt ein neues Objekt ohne diese Eigenschaft.
Jordi Nebot

32

Ich persönlich benutze Underscore.js oder Lodash für die Manipulation von Objekten und Arrays:

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


29

So klonen Sie ein Objekt ohne Eigenschaft:

Zum Beispiel:

let object = { a: 1, b: 2, c: 3 };   

Und wir müssen 'a' löschen.

1.Mit explizitem Requisitschlüssel:

const { a, ...rest } = object;
object = rest;

2.Mit variablem Propellerschlüssel:

const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;

3.Kühlpfeilfunktion 😎:

const removePropery = (propKey, { [propKey]: propValue, ...rest }) => rest;

object = removePropery('a', object);

4. Für mehrere Eigenschaften

const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})

Verwendungszweck

object = removeProperties(object, 'a', 'b') // result => { c: 3 }

Oder

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }

1
Slick-Pfeil-Funktion!
JSilv

27

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

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

Der Löschoperator entfernt eine bestimmte Eigenschaft aus einem Objekt. Nach erfolgreichem Löschen 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 Auswirkung und gibt true zurück

  • Wenn eine Eigenschaft mit demselben Namen in der Prototypenkette des Objekts vorhanden ist, verwendet das Objekt nach dem Löschen die Eigenschaft aus der Prototypenkette (mit anderen Worten, Löschen wirkt sich nur auf die eigenen Eigenschaften aus).

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

  • Daher kann delete 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 Bereich), 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. Dies umfasst Eigenschaften von integrierten Objekten wie Math, Array, Object und Eigenschaften, die mit Methoden wie Object.defineProperty () als nicht konfigurierbar erstellt wurden.

Das folgende Snippet gibt ein weiteres einfaches Beispiel:

var Employee = {
      age: 28,
      name: 'Alireza',
      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 Beispiele finden Sie unter folgendem Link:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete


22

Eine andere Lösung mit Array#reduce.

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

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

Das ursprüngliche Objekt wird jedoch mutiert . Wenn Sie ein neues Objekt ohne den angegebenen Schlüssel erstellen möchten , weisen Sie die Reduzierungsfunktion einfach einer neuen Variablen zu, z.

(ES6)

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

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);


21

Dieser Beitrag ist sehr alt und ich finde ihn sehr hilfreich. Deshalb habe ich beschlossen, die nicht gesetzte Funktion, die ich geschrieben habe, zu teilen, falls jemand anderes diesen Beitrag sieht und darüber nachdenkt, warum er nicht so einfach ist wie in der nicht gesetzten PHP-Funktion.

Der Grund für das Schreiben dieser neuen unsetFunktion besteht darin, den Index aller anderen Variablen in dieser hash_map beizubehalten. Schauen 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"}

20

Hier gibt es viele gute Antworten, aber ich möchte nur darauf hinweisen, dass es bei der Verwendung von delete zum Entfernen einer Eigenschaft in JavaScript häufig ratsam ist, zunächst zu überprüfen, 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 Dynamik von JavaScript gibt es häufig Fälle, in denen Sie einfach nicht wissen, ob die Eigenschaft vorhanden ist oder nicht. Wenn Sie überprüfen, ob obj vor dem && vorhanden ist, stellen Sie außerdem sicher, dass Sie keinen Fehler auslösen, wenn Sie die Funktion hasOwnProperty () für ein undefiniertes Objekt aufrufen.

Es tut uns leid, wenn dies nicht zu Ihrem speziellen Anwendungsfall beigetragen hat, aber ich glaube, dass dies ein gutes Design ist, das Sie beim Verwalten von Objekten und ihren Eigenschaften anpassen können.


2
foo.bar löschen funktioniert auch dann, wenn bar nicht vorhanden ist, also ist Ihr Test meiner Meinung nach etwas zu viel.
PhiLho

@PhiLho, das hängt davon ab, wo Sie JavaScript ausführen. In Node.js führt dies meines Erachtens zum Absturz Ihres Servers.
Willem

2
delete foo.bar;Löst nur dann eine Ausnahme aus, wenn foo falsch ist oder wenn Sie sich im strengen Modus befinden und foo ein Objekt mit einer nicht konfigurierbaren Balkeneigenschaft ist.
Macil

Ich erinnere mich nicht an das genaue Problem, das ich damit hatte, aber ich denke, das Problem kann auftreten, wenn foo selbst nicht existiert und Sie versuchen, seine Eigenschaft zu löschen.
Willem

Ja, Sie müssen testen, ob foo vorhanden ist, andernfalls löst foo.bar eine Ausnahme aus, aber Sie müssen die Existenz nicht auf bar überprüfen, bevor Sie sie löschen. Das ist der "zu viel" Teil meines Kommentars. :-)
PhiLho

16

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

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

Sie können auch andere Funktionen verwenden, um den gleichen Effekt zu erzielen - weglassen, auswählen, ...


15

Versuchen Sie die folgende Methode. Weisen Sie den ObjectEigenschaftswert 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);


1
AuchJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
Noisypixy

12

Wenn Sie eine tief im Objekt verschachtelte Eigenschaft löschen möchten, können Sie die folgende rekursive Funktion mit dem Pfad zur Eigenschaft als zweites Argument verwenden:

var deepObjectRemove = function(obj, path_to_key){
    if(path_to_key.length === 1){
        delete obj[path_to_key[0]];
        return true;
    }else{
        if(obj[path_to_key[0]])
            return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
        else
            return false;
    }
};

Beispiel:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}

Diese Funktion funktioniert wie ein Zauber, aber warum müssen wir true und false zurückgeben? Meine Version des Codes: codepen.io/anon/pen/rwbppY . Wird meine Version auf jeden Fall fehlschlagen?
Theusual

@ witty2017 es wird nicht scheitern. Der Ort, an dem ich die Funktion verwendet habe, musste auch überprüfen, ob die Eigenschaft bereits vorhanden ist oder nicht. Wenn die Eigenschaft nicht vorhanden ist, wird false zurückgegeben. Wenn die Eigenschaft gefunden und gelöscht wird, wird true zurückgegeben.
Ayushgp

8

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

Zum Beispiel:

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

key1Verwenden Sie beispielsweise das folgende deleteSchlüsselwort, um eine Eigenschaft zu entfernen :

delete obj.key1

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

delete obj[key1]

Ref: MDN .


8

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


7

Dans Behauptung, dass "Löschen" sehr langsam ist und der von ihm veröffentlichte Benchmark wurde angezweifelt. Also habe ich den Test selbst in Chrome 59 durchgeführt. Es scheint, dass "Löschen" etwa 30-mal langsamer ist:

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2);  // 205

Beachten Sie, dass ich absichtlich mehr als eine Löschoperation in einem Schleifenzyklus ausgeführt habe, um den durch die anderen Operationen verursachten Effekt zu minimieren.


7

Ziehen Sie in Betracht, ein neues Objekt ohne die "regex"Eigenschaft zu erstellen, da das ursprüngliche Objekt immer von anderen Teilen Ihres Programms 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);


SyntaxError: Unexpected token '...'. Expected a property name.?
Krzysztof Przygoda

Probieren Sie es mit einem modernen Browser wie Firefox, Chromium oder Safari aus. Und ich erwarte, dass es auch mit Edge funktioniert.
Ideaboxer

Wenn Ihre Kunden Sie dazu zwingen, veraltete Browser zu unterstützen, können Sie alternativ TypeScript verwenden, das Ihren Code in eine ältere Syntax umwandelt (+ bietet Ihnen den Vorteil der statischen Typensicherheit).
Ideaboxer

7

Entfernen von Eigenschaften in JavaScript

Auf dieser Seite werden viele verschiedene Optionen vorgestellt, nicht weil die meisten Optionen falsch sind - oder weil die Antworten doppelt sind -, sondern weil die geeignete Technik von der Situation und den Zielen der Aufgaben abhängt, die Sie und / oder Sie haben Team versuchen 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 die Sie Eigenschaften entfernen möchten, und der Typ der Eigenschaftsnamen, die Sie weglassen müssen (nur Zeichenfolgen? Symbole? Schwache Referenzen, die von beliebigen Objekten zugeordnet wurden? Dies sind seit Jahren alle Arten von Eigenschaftszeigern in JavaScript )
  3. Das Programmierethos / die Programmiermuster, die Sie und Ihr Team verwenden. Bevorzugen Sie funktionale Ansätze und Mutationen sind in Ihrem Team verboten, oder setzen Sie mutierte objektorientierte Wild-West-Techniken ein?
  4. Möchten Sie dies in reinem JavaScript erreichen oder sind Sie bereit und in der Lage, eine Bibliothek eines Drittanbieters zu verwenden?

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

Löschen mutativer Objekteigenschaften, unsicher

Diese Kategorie dient zum Bearbeiten von Objektliteralen oder Objektinstanzen, wenn Sie die ursprüngliche Referenz beibehalten / weiterhin verwenden möchten und keine zustandslosen 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 weitesten verbreitete Kategorie der Entfernung von Eigentum. Es unterstützt Symbol& Array-Indizes zusätzlich zu Zeichenfolgen und funktioniert in jeder Version von JavaScript mit Ausnahme der allerersten Version. Es ist jedoch eine Mutation, die gegen einige Programmierprinzipien verstößt und Auswirkungen auf die Leistung hat. Es kann auch zu nicht erfassten Ausnahmen führen, wenn nicht konfigurierbare Eigenschaften im strengen Modus verwendet werden .

Auslassungsbasierte Auslassung von Zeichenfolgeneigenschaften

Diese Kategorie ist für den Betrieb mit einfachen Objekt- oder Array-Instanzen in neueren ECMAScript-Varianten vorgesehen, wenn ein nicht mutativer Ansatz gewünscht wird und Sie keine Symbolschlüssel 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 dient zum Bearbeiten von Objektliteralen oder Objektinstanzen, wenn Sie die ursprüngliche Referenz beibehalten / weiterhin verwenden möchten, während Sie verhindern möchten, 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 verwenden Reflect.deleteProperty, um Teilanwendungen und andere funktionale Techniken auszuführen, die mit deleteAnweisungen nicht möglich sind .

Auslassen einer syntaxbasierten Zeichenfolgeeigenschaft

Diese Kategorie ist für den Betrieb mit einfachen Objekt- oder Array-Instanzen in neueren ECMAScript-Varianten vorgesehen, wenn ein nicht mutativer Ansatz gewünscht wird und Sie keine Symbolschlüssel 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 :(

Auslassung bibliotheksbasierter Eigenschaften

Diese Kategorie ermöglicht im Allgemeinen eine größere funktionale Flexibilität, einschließlich der Berücksichtigung von Symbolen und des Weglassens von mehr als einer Eigenschaft 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"

var keyname = "KeyName"; lösche myObject [keyname];
Vikash Chauhan

7

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

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

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


@CoddWrench Entschuldigung, ich habe nicht darauf geachtet, diese Antwort zu sehen. Ich antworte sofort nach dem Sehen delete myObject.regex;.
Xiang

7

Sie können die ES6-Destrukturierung mit dem Restoperator verwenden.

Eigenschaften können durch Destrukturierung in Kombination mit dem Restoperator entfernt werden . In Ihrem Beispiel wird Regex zerstört (ignoriert) und der Rest der Eigenschaften wird als Rest zurückgegeben.

const noRegex = ({ regex, ...rest }) => rest;
const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

console.log(noRegex(myObjext)) //=> {  "ircEvent": "PRIVMSG","method": "newURI" }

Oder Sie können Eigenschaften wie diese dynamisch ausschließen.

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest

const removeRegex = removeProperty('regex') //=> {  "ircEvent": "PRIVMSG","method":"newURI" }
const removeMethod = removeProperty('method') //=> {  "ircEvent": "PRIVMSG", "regex":"^http://.*" }

7

Wir können jede Eigenschaft aus einem Javascript-Objekt entfernen, indem wir Folgendes verwenden:

  1. object.property löschen
  2. Objekt löschen ['Eigenschaft']

Beispiel:

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

console.log(myObject);

delete myObject.regex;
console.log('=================');
console.log(myObject);
delete myObject['method'];
console.log('=================');
console.log(myObject);


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.