Wie entferne ich eine Eigenschaft von einem Javascript-Objekt?

Nehmen wir an, ich erstelle so ein Objekt:

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

Was ist der beste Weg, um die regex Eigenschaft zu entfernen, um ein neues myObject wie myObject :

 var myObject = { "ircEvent": "PRIVMSG", "method": "newURI" }; 
5276
16 окт. setze johnstok 16 oct. 2008-10-16 13:57 08 um 13:57 2008-10-16 13:57
@ 37 Antworten
  • 1
  • 2

So:

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

Demo

kangax einen unglaublich detaillierten Blogbeitrag über die Löschanweisung in seinem Blog geschrieben.  Sehr zu empfehlen. 

7292
16 окт. die antwort ist nickf 16 oct. 2008-10-16 13:58 08 um 13:58 2008-10-16 13:58

Operator delete unerwartet ver>

Schau dir die Benchmark an .

Löschen ist der einzig sichere Weg, um die Eigenschaften eines Objekts ohne Residuen zu entfernen, aber es arbeitet ~ 100 Mal > als das "alternative" Einstellungsobjekt object[key] = undefined .

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

Wann sollte delete verwendet werden und wann ist der angegebene Wert undefined ?

Ein Objekt kann als ein Satz von Schlüsselwertpaaren betrachtet werden. Was ich "Wert" nenne, ist ein Grundelement oder ein Verweis auf ein anderes Objekt, das diesem "Schlüssel" zugeordnet ist.

Verwenden Sie delete wenn Sie ein Ergebnisobjekt an einen Code übergeben, auf den Sie keine Kontrolle haben (oder wenn Sie nicht in Ihr Team oder sich selbst vertrauen).

Es entfernt den Schlüssel von der Hash-Karte .

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

Wenn Sie sich bezüglich der Leistung nicht sicher sind, verwenden Sie die Option undefined . Dies kann Ihren Code ernsthaft beeinträchtigen.

Der Schlüssel bleibt an seiner Stelle in der Hashmap , nur der Wert wird durch undefined . Verstehen Sie, dass der for..in Zyklus diesen Schlüssel noch durchläuft.

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

Bei Verwendung dieser Methode funktionieren nicht alle Methoden zum Bestimmen der Existenzeigenschaft wie erwartet.

Dieser Code ist jedoch:

object.field === undefined

verhält sich für beide Methoden gleichwertig.

Tests

Zusammenfassend gibt es Unterschiede bei der Ermittlung der Existenz einer Eigenschaft und for..in Schleife.

border=0
  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\ 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!

Obwohl obj[prop] = undefined schneller ist als delete obj[prop] , ist eine weitere wichtige Überlegung, dass obj[prop] = undefined nicht immer relevant ist. delete obj[prop] entfernt die prop aus obj und löscht sie aus dem Gedächtnis, während obj[prop] = undefined den prop Wert einfach auf undefined wodurch die prop noch in Erinnerung bleibt. Daher kann die Verwendung von obj[prop] = undefined in Situationen, in denen viele Schlüssel erstellt und gelöscht werden, zu kostspieliger Speicherkonsistenz (das Einfrieren der Seite) und möglicherweise zu einem Speicherfehler führen. 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 ); }); 

Im obigen Code ist gerade nodeRecords[i][lastTime] = undefined; führt bei jedem Animationsbild zu einem massiven Speicherverlust. In jedem Frame werden alle Elemente von 65536 DOM um weitere 65.536 einzelne Slots belegt. Die vorherigen Slots 65.536 werden jedoch nur auf undefiniert gesetzt, sodass sie im Speicher bleiben. Fahren Sie fort, versuchen Sie, den obigen Code in der Konsole auszuführen, und überzeugen Sie sich selbst. Versuchen Sie es nach einem erzwungenen Speicherfehler erneut auszuführen, mit Ausnahme der nächsten Version des Codes, die 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 aus dem obigen Code-Snippet ersichtlich, gibt es einige selten geeignete Verwendungsmöglichkeiten für den delete . Sorgen Sie sich jedoch nicht zu sehr um dieses Problem. Dies wird nur bei Objekten mit >obj[prop] = undefined . Der Hauptzweck dieses Abschnitts besteht darin, Sie einfach darauf aufmerksam zu machen, dass es in seltenen Fällen zu einem Problem in Ihrem Code kommt. Dann können Sie das Problem leichter verstehen und sollten daher keine Zeit damit verbringen, Ihren Code zu analysieren, um dieses Problem zu finden und zu verstehen.

Nicht immer auf undefined

Ein wichtiger Aspekt von Javascript ist der Polymorphismus. Polymorphismus ist die Zuweisung identischer Variablen / Slots in Objekten unterschiedlichen Typs, wie unten gezeigt.

 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 

Es gibt jedoch zwei Hauptprobleme, die bei Verwendung polymorpher Arrays nicht behoben werden können:

  1. Sie sind >
  2. Nach polymorph, immer polymorph. Wenn ein Array polymorph gemacht wird, kann der Polymorphismus in Webkit-Browsern nicht abgebrochen werden. Selbst wenn Sie ein polymorphes Array als nicht-polymorph wiederherstellen, wird es vom Browser als polymorphes Array gespeichert.

Sie können den Polymorphismus der Drogensucht vergleichen. Auf den ersten Blick scheint es unglaublich profitabel zu sein: ein schöner, eher flockiger Code. Der Kodierer gibt dann sein Array in ein Polymorphismus-Medikament ein. Sofort wird eine polymorphe Matrix weniger effektiv und kann nie so effektiv werden wie zuvor, da sie anästhesiert wird. Um einen solchen Umstand mit dem wirklichen Leben in Verbindung zu bringen, kann jemand aus Kokain möglicherweise nicht einmal einen einfachen Türgriff bedienen oder gar die PI-Zahlen berechnen. Ebenso kann ein Array auf einem Polymorphismus-Präparat nicht so effektiv sein wie ein monomorphes Array.

Wie aber bezieht sich die Drogenanalogie auf die delete ? Die Antwort enthält die letzte Codezeile im obigen Snippet. Lassen Sie es also überarbeitet werden, 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 

Beachten Sie. bar[1] = "" keinen Polymorphismus, wohingegen bar[1] = undefined ist. Daher ist es immer notwendig, wenn möglich, den geeigneten Typ für Ihre Objekte zu verwenden, um nicht versehentlich Polymorphismus zu verursachen. Eine solche Person kann die folgende Liste als allgemeinen Link verwenden, um sie zu erhalten. Bitte verwenden Sie jedoch nicht die folgenden Ideen. Verwenden Sie stattdessen das, was für Ihren Code gut geeignet ist.

  • Wenn Sie ein Array / eine Variable verwenden, die in einem booleschen Grundelement eingegeben wurde, verwenden Sie den Wert false oder undefined als leeren Wert. Das Vermeiden von unnötigem Polymorphismus ist zwar gut, aber das erneute Schreiben des gesamten Codes zum ausdrücklichen Deaktivieren führt wahrscheinlich zu einer schlechten Leistung. Verwenden Sie ein gutes Urteilsvermögen
  • Wenn Sie ein Array / eine Variable verwenden, die in einem numerischen Grundelement eingegeben wird, verwenden Sie 0 als leeren Wert. Beachten Sie, dass es zwei Arten von Zahlen gibt: schnelle Ganzzahlen (von 2147483647 bis einschließlich -2147483648) und >NaN und Infinity ). Wenn eine ganze Zahl doppelt ist, kann sie nicht als ganze Zahl klassifiziert werden.
  • Wenn Sie ein Array / eine Variable verwenden, die in einem String-Grundelement eingegeben wurde, verwenden Sie "" als leeren Wert.
  • Warten Sie, wenn Sie das Symbol verwenden, warum verwenden Sie das Symbol?!?! Schlechte Juju-Charaktere für Leistung. Alle für die Verwendung programmierten Zeichen können so umprogrammiert werden, dass keine Zeichen verwendet werden. Dies führt zu einem schnelleren Code ohne Code. Symbole sind in Wirklichkeit nur ein ineffektiver Metazucker.
  • Wenn Sie etwas anderes verwenden, verwenden Sie null .

Seien Sie jedoch vorsichtig! Beginnen Sie nicht damit, den gesamten vorhandenen Code zu verwenden, da er den vorhandenen Code beschädigen und / oder ungewöhnliche Fehler anzeigen kann. Vielmehr sollte eine solche effektive Praxis von Anfang an implementiert werden, und es wird empfohlen, bei der Konvertierung von vorhandenem Code alle diesbezüglichen Zeilen zu verdoppeln, zu verdreifachen, zu vervierfachen, da ein Versuch, den alten Code auf diese neue Praxis umzustellen, ebenso riskant wie nützlich sein kann. .

770
12 февр. Antworten Dan 12 Feb 2014-02-12 20:48 14 um 20:48 2014-02-12 20:48

215
16 окт. Antwort an redsquare am 16. Oktober 2008-10-16 14:03 08 um 14:03 Uhr 2008-10-16 14:03 Uhr

Update 2018-07-21: Diese Antwort hat mich >


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 

Massives Äquivalent

Nicht aus dem Array delete Array.prototype.splice dieses verwenden Array.prototype.splice .

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

>

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

Im Gegensatz zu einfachen alten Objekten hinterlässt die Verwendung von delete Papierkorb in Form von null , wodurch ein "Loch" im Array entsteht.

 var array = [1, 2, 3, 4]; delete array[2];  

Wie Sie sehen, funktioniert das delete nicht immer wie erwartet. Der Wert wird überschrieben, der Speicher wird jedoch nicht neu verteilt. Mit anderen Worten, array[4] bewegt sich nicht zu array[3] . Im Gegensatz zu Array.prototype.unshift , das ein Element am Anfang eines Arrays einfügt und alles nach oben Array.prototype.unshift ( array[0] wird zu array[1] usw.),

Neben dem Setzen von null und nicht undefined - was völlig seltsam ist - sollte dieses Verhalten nicht überraschen, da delete ein unärer Operator ist, wie typeof , der starr in die Sprache gedreht ist und sich nicht um die Art des verwendeten Objekts kümmern sollte. Array ist eine Unterklasse von Object mit Methoden, die speziell für das Arbeiten mit Arrays entwickelt wurden. Daher gibt es keinen Grund für das delete , um einen Spezialfall vorbereiten zu können, um ein Array erneut zu verschieben, da dies die Arbeit mit unnötiger Arbeit ver>

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

Das Ignorieren der Gefahren und Probleme, die mit null und verschwendetem Speicherplatz verbunden sind, kann problematisch sein, wenn das Array genau sein muss.

Was eine schreckliche Ausrede ist, um null s loszuwerden - null ist gefährlich, wenn es falsch verwendet wird, und hat nichts mit "Genauigkeit" zu tun. Der eigentliche Grund, warum Sie nicht aus einem Array delete sollten, ist, dass das Verwischen der mit Datenmüll gefüllten und schmutzigen Datenstrukturen unübersichtlich und fehleranfällig ist

Nachfolgend finden Sie ein konstruiertes Skript, das recht >"Lösung" gehen können. Der einzige Grund, warum ich diesen Abschnitt verlasse, ist, dass ich denke, dass einige Leute es wahrscheinlich lustig finden, und ich möchte nicht der „Kerl“ sein, der die „lustige“ Antwort sendet und sie dann löscht. alles "lustig",

... Das ist dumm, ich weiß.

Das gestaltete und >

Angenommen, Sie erstellen eine Webanwendung, die JSON-Serialisierung verwendet, um das für die Registerkarten verwendete Array in einer Zeichenfolge zu speichern (in diesem Fall localStorage ). Lassen Sie sie auch sagen, dass der Code die numerischen Indizes der Elemente des Arrays verwendet, um sie beim Zeichnen auf dem Bildschirm zu "benennen". Warum tust du das und behält nicht nur den "Titel"? Weil ... Gründe.

Nun, lassen Sie mich sagen, dass Sie versuchen, Speicher auf Anforderung dieses einen Benutzers zu speichern, der den PDP-11-Minicomputer seit 1960 ausführt und UNIX ausführt und eine eigene JavaScript-kompatible Schnittstelle mit JavaScript-Browser-Unterstützung geschrieben hat, da X11 dies nicht ist nicht in Frage.

Ein zunehmend dummes Skript des Rand-Skripts, das delete im angegebenen Array verwendet, macht null Verschmutzung des Arrays ungültig und führt später wahrscheinlich zu Fehlern in der Anwendung. Wenn Sie null , werden die Zahlen automatisch übersprungen. Die angezeigten Registerkarten sehen dann wie folgt aus: [1] [2] [4] [5]...

 if (array[index] == null) continue; else title = (index + 1).toString();  

Ja, das ist definitiv nicht das, was Sie wollten.

Jetzt können Sie den zweiten Iterator, z. B. j , speichern, um nur zu erhöhen, wenn tatsächliche Werte aus dem Array gelesen werden. Aber es löst definitiv nicht das null Problem und Sie mögen diesen Troll PDP-11-Benutzer immer noch. Leider hat sein Computer einfach nicht genug Speicherplatz, um diese letzte Ganzzahl zu speichern (fragen Sie nicht, wie er ein Array mit variabler Breite handhabt ...) .

Also schickt er dir einen Brief 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 

Jetzt bist du an deinem Ende. Dieser Kerl hat sich ständig über Ihre Anwendung beschwert und Sie möchten ihm sagen, dass er den Mund halten und zum besten Computer gehen soll.

Lösung: Array.prototype.splice

Glücklicherweise verfügen Arrays über eine spezielle Methode zum Entfernen 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 sind Sie mit Herrn PDP-11 zufrieden. Hurra! (Ich würde es ihm trotzdem sagen ...)

Array.prototype.splice vs Array.prototype.slice

Ich finde es wichtig, den Unterschied zwischen diesen beiden ähnlich benannten Funktionen zu beachten, da beide sehr nützlich sind.

Array.prototype.splice (Start, n)

.splice() ein Array und gibt entfernte Indizes zurück. Das Array wird ausgehend vom Index ausgeschnitten, start und n Elemente werden abgeschnitten. Wenn n nicht angegeben ist, ist das gesamte Array nach dem start n = array.length - start ( 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 die Endindizes aus irgendeinem Grund bei 1 statt bei 0 beginnen. Ich weiß nicht, warum dies passiert, aber es ist der Fall. Wenn end <= start , ist das Ergebnis außerdem 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] 

Tatsächlich geschieht dies nicht, aber es ist leichter, darüber nachzudenken. Laut MDN geschieht dies tatsächlich:

 // 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 Indizes in Klammern geben an, was geschnitten wird. In jedem Fall ist das Verhalten nicht intuitiv und beruht auf der Tatsache, dass es einen angemessenen Fehleranteil "nacheinander" verursacht. .splice() kann es sinnvoll sein, den Wrapper mehr als .splice() Verhaltens von .splice() :

 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]  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 für sehr starke Typen bestimmt ist und null zurückgibt, wenn etwas deaktiviert ist. Dazu gehört eine Zeichenfolge vom Typ "3" . Es bleibt dem Programmierer überlassen, in seinem Typ fleißig zu sein. Dies sollte zu einer guten Programmierpraxis beitragen.

Update bezüglich is_array()

Dies gilt für dieses (jetzt gelöschte) Fragment:

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

Wie sich herausgestellt hat, gibt es tatsächlich eine integrierte Methode, um festzustellen, ob ein Array wirklich ein Array ist. Dies ist Array.isArray() , das in ECMAScript 5 (Dezember 2009) eingeführt wurde. Я нашел это, глядя на вопрос, есть ли вопрос о том, чтобы сообщать массивы с объектов, чтобы увидеть, было ли лучшее решение, чем мое, или добавить мое, если их не было. Итак, если вы используете версию JavaScript, которая раньше ECMA 5, там ваш полипол. Тем не менее, я настоятельно рекомендую не использовать is_array() , так как продолжение поддержки старых версий JavaScript означает продолжение поддержки старых браузеров, которые их реализуют, что означает поощрение использования небезопасного программного обеспечения и помещение пользователей под угрозу для вредоносного ПО. Поэтому, пожалуйста, используйте Array.isArray() . Используйте let и const . Используйте новые функции, которые добавляются в язык. Не используйте префиксы поставщиков. Удалите это полисплощадку IE с вашего сайта. Удалите этот XHTML <!CDATA[[... crap, тоже - мы переместились в HTML5 еще в 2014 году.). Чем раньше все откажутся от поддержки этих старых/эзотерических браузеров, тем скорее поставщики браузеров будут действительно следовать веб-стандарту и охватывают новые технологии, и чем скорее мы сможем перейти к более безопасной сети.

164
ответ дан Braden Best 18 сент. '12 в 3:56 2012-09-18 03:56

Старый вопрос, современный ответ. Используя деструктурирование объектов, ECMAScript 6 , это так же просто, как:

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

Или с образцом вопросов:

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

Вы можете увидеть его в действии в редакторе Babel try-out.


Bearbeiten:

Чтобы переназначить одну и ту же переменную, используйте let :

 let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; ({ regex, ...myObject } = myObject); console.log(myObject); 
126
Die Antwort wird von Koen gegeben. 08 нояб. '16 в 21:02 2016-11-08 21:02

Другой альтернативой является использование библиотеки Underscore.js .

Обратите внимание, что _.pick() и _.omit() возвращают копию объекта и не изменяют напрямую оригинальный объект. Присвоение результата исходному объекту должно выполнить трюк (не показан).

Ссылка: ссылка _.pick (объект, * ключи)

Вернуть копию объекта, отфильтровать, чтобы иметь только значения для белых ключей (или массива действительных ключей).

 var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; _.pick(myJSONObject, "ircEvent", "method"); => {"ircEvent": "PRIVMSG", "method": "newURI"}; 

Ссылка: ссылка _.omit (объект, * ключи)

Верните копию объекта, отфильтрованную, чтобы опустить вложенные в черный список ключи (или массив ключей).

 var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; _.omit(myJSONObject, "regex"); => {"ircEvent": "PRIVMSG", "method": "newURI"}; 

Для массивов, _.filter() и _.reject() могут использоваться аналогичным образом.

80
ответ дан Thaddeus Albers 24 мая '14 в 21:53 2014-05-24 21:53

Термин, который вы использовали в заголовке вопроса Remove a property from a JavaScript object , может быть интерпретирован несколькими способами. Один из них заключается в том, чтобы удалить его для всей памяти, а список объектных ключей или другой - просто удалить его из вашего объекта. Как уже упоминалось в некоторых других ответах, ключевое слово delete является основной частью. Скажем, у вас есть свой объект:

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

Wenn du rennst:

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

результатом будет:

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

Вы можете удалить этот конкретный ключ из ваших объектных клавиш, например:

 delete myJSONObject["regex"]; 

Тогда ключ ваших объектов с помощью Object.keys(myJSONObject) будет выглядеть следующим образом:

 ["ircEvent", "method"] 

Но дело в том, что если вы заботитесь о памяти и хотите, чтобы весь объект удалялся из памяти, рекомендуется установить его значение null до удаления ключа:

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

Другим важным моментом здесь является осторожность в отношении других ссылок на один и тот же объект. Например, если вы создаете переменную типа:

 var regex = myJSONObject["regex"]; 

Или добавьте его как новый указатель на другой объект, например:

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

Тогда даже если вы удалите его из своего объекта myJSONObject , этот конкретный объект не будет удален из памяти, так как переменная regex и myOtherObject["regex"] все еще имеют свои значения. Тогда как мы могли бы точно удалить объект из памяти?

Ответ будет удалить все ссылки, которые у вас есть в вашем коде, указал на тот самый объект , а также не использовать var для создания новых ссылок на этот объект . Этот последний пункт в отношении операторов var является одной из наиболее важных проблем, с которыми мы обычно сталкиваемся, поскольку использование операторов var предотвратит удаление объекта, созданного.

Это означает, что в этом случае вы не сможете удалить этот объект, потому что вы создали переменную regex с помощью инструкции var , и если вы это сделаете:

 delete regex; //False 

Результат будет false , что означает, что ваш оператор удаления не был выполнен, как вы ожидали. Но если вы еще не создали эту переменную, и у вас была только myOtherObject["regex"] как ваша последняя существующая ссылка, вы могли бы сделать это, просто удалив ее, как:

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

Другими словами, объект JavaScript будет убит, как только в коде не будет указана ссылка на этот объект.


Update: Благодаря @AgentME:

Установка свойства null перед удалением не выполняется ничего (если объект не был закрыт объектом Object.seal и удаление не выполняется. Это обычно не так, если вы специально попробовать).

Чтобы получить дополнительную информацию по Object.seal : Object.seal()

42
ответ дан Mehran Hatami 12 февр. '14 в 9:29 2014-02-12 09:29

Предположим, что у вас есть объект, который выглядит так:

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

Удаление свойства объекта

Если вы хотите использовать весь массив staff , правильный способ сделать это:

 delete Hogwarts.staff; 

В качестве альтернативы вы также можете сделать это:

 delete Hogwarts['staff']; 

Аналогично, удаление всего массива студентов будет выполняться путем вызова delete Hogwarts.students; или delete Hogwarts['students']; .

Удаление индекса массива

Теперь, если вы хотите удалить одного сотрудника или ученика, процедура немного отличается, потому что оба свойства сами являются массивами.

Если вы знаете индекс своего сотрудника, вы можете просто сделать это:

 Hogwarts.staff.splice(3, 1); 

Если вы не знаете индекс, вам также нужно будет выполнить поиск по индексу:

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

Примечание

Хотя вы технически можете использовать delete для массива, использование его приведет к получению неверных результатов при вызове, например, Hogwarts.staff.length позже. Другими словами, delete удалит элемент, но он не обновит значение свойства length . Использование delete также испортило бы вашу индексацию.

Таким образом, при удалении значений из объекта всегда сначала учитывайте, имеете ли вы дело с объектами или имеете дело с значениями массива и выбираете на основе соответствующей стратегии.

Если вы хотите поэкспериментировать с этим, вы можете использовать этот скрипт в качестве отправной точки.

33
21 февр. Antwort von John Slegers 21 Feb. '16 в 21:09 2016-02-21 21:09

ECMAScript 2015 (или ES6) поставляется со встроенным Reflect объектом. Свойства объекта можно удалить, вызвав функцию Reflect.deleteProperty() с целевым объектом и ключом свойства в качестве параметров:

 Reflect.deleteProperty(myJSONObject, 'regex'); 

что эквивалентно:

 delete myJSONObject['regex']; 

Но если свойство объекта не настраивается, оно не может быть удалено ни с помощью функции deleteProperty, ни при удалении оператора:

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

Object.freeze() делает все свойства объекта не настраиваемыми (помимо прочего). Функция deleteProperty (а также удалить оператор ) возвращает false при попытке удалить любые ее свойства. Если свойство настраивается, оно возвращает true , даже если свойство не существует.

Разница между delete и deleteProperty заключается в использовании строгого режима:

 "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 
32
ответ дан madox2 10 янв. '16 в 19:36 2016-01-10 19:36

Синтаксис распространения (ES6)

Для тех, кто нуждается в этом...

Чтобы завершить ответ @Koen в этой теме, на случай, если вы захотите удалить динамическую переменную, используя синтаксис распространения, вы можете сделать это так:

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

* foo будет новой переменной со значением a (которое равно 1).


UPDATE :
Существует несколько распространенных способов удаления свойства из объекта.
У каждого есть свои плюсы и минусы ( проверьте это сравнение производительности ):

Оператор удаления
Удобный для чтения и краткий, однако он может быть не лучшим выбором, если вы работаете с большим количеством объектов, поскольку его производительность не оптимизирована.

 delete obj[key]; 


Перераспределение
Более чем в 2 раза быстрее, чем delete , однако свойство не удаляется и может быть повторено.

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


Оператор распространения
Этот оператор ES6 позволяет нам возвращать новый объект, исключая любые свойства, без изменения существующего объекта. Недостатком является то, что он имеет худшую производительность из вышеперечисленных и не рекомендуется использовать, когда вам нужно удалить много свойств одновременно.

 { [key]: val, ...rest } = obj; 
29
ответ дан Lior Elrom 12 сент. '18 в 21:39 2018-09-12 21:39

удалить оператор - лучший способ сделать это.

Живой пример для показа:

 var foo = {bar: 'bar'}; delete foo.bar; console.log('bar' in foo); // Logs false, because bar was deleted from foo. 
25
ответ дан Tarun Nagpal 28 апр. '15 в 8:14 2015-04-28 08:14

Я лично использую Underscore.js или Lodash для манипулирования объектами и массивами:

 myObject = _.omit(myObject, 'regex'); 
22
ответ дан emil 22 янв. '16 в 5:29 2016-01-22 05:29

Использование метода удаления - лучший способ сделать это, согласно описанию MDN, оператор delete удаляет свойство из объекта. Поэтому вы можете просто написать:

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

Оператор delete удаляет заданное свойство из объекта. При успешном удалении оно вернет true, иначе будет возвращено false. Однако важно учитывать следующие сценарии:

  • Если свойство, которое вы пытаетесь удалить, не существует, delete не будет иметь никакого эффекта и вернет true

  • Если свойство с тем же именем существует в цепочке прототипов объекта, то после удаления объект будет использовать свойство из цепи прототипа (другими словами, удаление влияет только на собственные свойства).

  • Любое свойство, объявленное с помощью var, не может быть удалено из глобальной области или из области действия.

  • Таким образом, delete не может удалить какие-либо функции в глобальной области (независимо от того, является ли это частью определения функции или функции (выражение).

  • Функции, которые являются частью объекта (кроме
    глобальная область действия) можно удалить с помощью удаления.

  • Любое свойство, объявленное с let или const, не может быть удалено из области действия, в которой они были определены. Неконфигурируемые свойства не могут быть удалены. Сюда входят свойства встроенных объектов, таких как Math, Array, Object и свойства, которые создаются как неконфигурируемые с помощью методов Object.defineProperty().

Следующий фрагмент дает еще один простой пример:

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

18
ответ дан Alireza 07 апр. '17 в 19:16 2017-04-07 19:16

Другое решение, использующее Array#reduce .

 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); 
18
ответ дан kind user 26 марта '17 в 18:19 2017-03-26 18:19

Эта статья очень старая, и я считаю ее очень полезной, поэтому я решил поделиться функцией unset, которую я написал, в случае, если кто-то еще увидит это сообщение и подумает, почему это не так просто, как в функции отмены PHP.

Причиной написания этой новой функции unset является сохранение индекса всех других переменных в этой hash_map. Посмотрите на следующий пример и посмотрите, как индекс "test2" не изменился после удаления значения из hash_map.

 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"} 
17
ответ дан talsibony 01 дек. '14 в 10:33 2014-12-01 10:33

Здесь есть много хороших @, но я просто хочу услышать, что при использовании delete для удаления свойства в JavaScript часто бывает полезно сначала проверить, существует ли это свойство для предотвращения ошибок.

zum beispiel

 var obj = {"property":"value", "property2":"value"}; if (obj  obj.hasOwnProperty("property2")) { delete obj.property2; } else { //error handling } 

Из-за динамического характера JavaScript часто бывают случаи, когда вы просто не знаете, существует ли свойство или нет. Проверка существования obj до также гарантирует, что вы не выкидываете ошибку из-за вызова функции hasOwnProperty() объекта undefined.

Извините, если это не добавило вашего конкретного варианта использования, но я считаю, что это хороший дизайн для адаптации при управлении объектами и их свойствами.

16
ответ дан Willem 15 сент. '14 в 3:48 2014-09-15 03:48

Используя ramda # dissoc , вы получите новый объект без атрибута regex :

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

Вы также можете использовать другие функции для достижения того же эффекта - опустить, выбрать,...

12
ответ дан zatziky 28 нояб. '16 в 18:14 2016-11-28 18:14

Попробуйте использовать следующий метод. Назначьте значение свойства Object undefined . Затем stringify объект и parse .

11
ответ дан Mohammed Safeer 06 июля '16 в 17:51 2016-07-06 17:51

Если вы хотите удалить свойство, глубоко вложенное в объект, вы можете использовать следующую рекурсивную функцию с указанием пути к свойству в качестве второго аргумента:

 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: {}}} 
11
ответ дан ayushgp 23 июня '16 в 12:38 2016-06-23 12:38

Использование ES6:

(Оператор Destructuring + Spread)

  const myObject = { regex: "^http://.*", b: 2, c: 3 }; const { regex, ...noRegex } = myObject; console.log(noRegex); // => { b: 2, c: 3 } 
8
ответ дан Srinivas 23 июля '18 в 18:52 2018-07-23 18:52

Вы можете просто удалить любое свойство объекта, используя ключевое слово delete .

Zum Beispiel:

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

Чтобы удалить любое свойство, например key1 , используйте ключевое слово delete следующим образом:

 delete obj.key1 

Или вы также можете использовать массивную нотацию:

 delete obj[key1] 

Ссылка: MDN .

7
ответ дан Kalpesh Patel 07 апр. '16 в 8:46 2016-04-07 08:46

Рассмотрите возможность создания нового объекта без свойства "regex" , поскольку исходный объект всегда может ссылаться на другие части вашей программы. Таким образом, вам следует избегать манипулирования им.

6
ответ дан ideaboxer 23 окт. '17 в 13:06 2017-10-23 13:06

Утверждение Дэна о том, что "удаление" происходит очень медленно, и поставленный в нем тест был усомнился. Поэтому я сам проверил тест в Chrome 59. Кажется, что "delete" примерно в 30 раз медленнее:

 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 oa; delete ob; delete oc; delete od; delete oe; } 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}; oa = ob = oc = od = oe = undefined; } console.log (Date.now()-t2); // 205 

Обратите внимание, что я специально выполнял несколько операций "удалить" в одном цикле цикла, чтобы минимизировать эффект, вызванный другими операциями.

6
ответ дан Chong Lip Phang 26 июля '17 в 10:19 2017-07-26 10:19

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

6
19 сент. Die Antwort wird gegeben xgqfrms-gildata 19. September '17 в 11:37 2017-09-19 11:37

5
ответ дан xiang 06 февр. '18 в 7:28 2018-02-06 07:28

Probiere es aus

 delete myObject['key']; 
5
ответ дан codemirror 26 мая '17 в 9:58 2017-05-26 09:58

Здравствуйте, Вы можете попробовать этот простой вид

 var obj = []; obj.key1 = {name: "John", room: 1234}; obj.key2 = {name: "Jim", room: 1234}; delete(obj.key1); 
5
ответ дан Dhaval Gohel 26 мая '17 в 12:28 2017-05-26 12:28

Удаление имущества в JavaScript

На этой странице представлено множество различных вариантов, а не потому, что большинство вариантов неверны, или потому, что ответы являются дубликатами, а потому, что соответствующий метод зависит от ситуации, в которой вы находитесь, и целей задач, которые вы и/или вы команда пытается выполнить. Чтобы ответить на ваш вопрос однозначно, нужно знать:

  1. Версия ECMAScript, на которую вы нацеливаетесь
  2. Диапазон типов объектов, которые вы хотите удалить, и типы имен свойств, которые вам нужно упускать (только строки) Символы? Слабые ссылки, сопоставленные с произвольными объектами? Все это были типы указателей свойств в JavaScript уже много лет )
  3. Этимы/шаблоны программирования, которые вы и ваша команда используете. Поддерживаете ли вы функциональные подходы, а мутация - в вашей команде, или вы используете дикие западные мутативные объектно-ориентированные методы?
  4. Вы хотите добиться этого в чистом JavaScript или хотите ли вы использовать стороннюю библиотеку?

После ответа на эти четыре вопроса в JavaScript есть по существу четыре категории "удаление собственности" на JavaScript, чтобы соответствовать вашим целям. Они есть:

Удаление мутативного объекта, небезопасное

Эта категория предназначена для работы с объектными литералами или экземплярами объектов, когда вы хотите сохранить/продолжить использовать исходную ссылку и не используете в своем коде функциональные принципы без состояния. Пример синтаксиса в этой категории:

 '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 

Эта категория является самой старой, самой простой и наиболее широко распространенной категорией удаления собственности. Он поддерживает индексы Symbol array в дополнение к строкам и работает в каждой версии JavaScript, за исключением самой первой версии. Однако это мутация, которая нарушает некоторые принципы программирования и имеет последствия для производительности. Это также может привести к неперехваченным исключениям при использовании в неконфигурируемых свойствах в строгом режиме .

Исключение свойств строки на основе Rest

Эта категория предназначена для работы с экземплярами простого объекта или массива в новых вариантах ECMAScript, когда требуется не-мутирующий подход, и вам не нужно учитывать ключи Symbol:

 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 :( 

Удаление мутативного объекта, безопасное

Эта категория предназначена для работы с объектными литералами или экземплярами объектов, когда вы хотите сохранить/продолжать использовать исходную ссылку, защищая от исключений, возникающих при неконфигурируемых свойствах:

 '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 

Кроме того, в то время как мутация объектов на месте не является апатридом, вы можете использовать функциональный характер Reflect.deleteProperty для частичного приложения и других функциональных методов, которые невозможны с инструкциями delete .

Бездействие на основе синтаксиса

Эта категория предназначена для работы с экземплярами простого объекта или массива в новых вариантах ECMAScript, когда требуется не-мутирующий подход, и вам не нужно учитывать ключи Symbol:

 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 :( 

Исключение имущества на базе библиотеки

Эта категория, как правило, обеспечивает большую функциональную гибкость, включая учет символов и исключение более одного свойства в одном заявлении:

 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" 
4
ответ дан james_womack 14 дек. '17 в 5:35 2017-12-14 05:35

Использование lodash

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

Использование Ramda

 R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3} 
4
ответ дан johndavedecano 14 сент. '17 в 17:14 2017-09-14 17:14

@johnstock , мы также можем использовать концепцию прототипирования JavaScript, чтобы добавить метод к объектам для удаления любого переданного ключа, доступного в вызывающем объекте.

Выше ответы приветствуются.

 var myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; // 1st and direct way delete myObject.regex; // delete myObject["regex"] console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' } // 2 way - by using the concept of JavaScript prototyping concept Object.prototype.removeFromObjectByKey = function(key) { // If key exists, remove it and return true if(this[key] !== undefined) { delete this[key] return true; } // Else return false return false; } var isRemoved = myObject.removeFromObjectByKey('method') console.log(myObject) // { ircEvent: 'PRIVMSG' } // More examples var obj = { a: 45, b: 56, c: 67} console.log(obj) // { a: 45, b: 56, c: 67 } // Remove key 'a' from obj isRemoved = obj.removeFromObjectByKey('a') console.log(isRemoved); //true console.log(obj); // { b: 56, c: 67 } // Remove key 'd' from obj which doesn't exist var isRemoved = obj.removeFromObjectByKey('d') console.log(isRemoved); // false console.log(obj); // { b: 56, c: 67 } 
3
ответ дан hygull 24 мая '18 в 21:42 2018-05-24 21:42
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос