Come rimuovo una proprietà da un oggetto JavaScript?


6142

Di 'che creo un oggetto come segue:

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

Qual è il modo migliore per rimuovere la proprietà regexper finire con nuovi myObjectcome segue?

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


@EscapeNetscape Questa è una domanda riguardante il comportamento, quindi un punto di riferimento dipinge l'immagine sbagliata. Naturalmente deletesarebbe l'opzione più lenta poiché è un'operazione effettiva piuttosto che le altre due che sono solo semplici incarichi. Ma il nocciolo della questione è che l'assegnazione della proprietà a nullo undefinednon rimuove effettivamente la proprietà dall'oggetto, ma imposta invece quella proprietà su un valore costante costante. (Di seguito le risposte
spiegano

Risposte:


8307

Come questo:

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

dimostrazione

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

console.log(myObject);

Per chiunque sia interessato a saperne di più, l'utente di Stack Overflow kangax ha scritto un post sul blog incredibilmente approfondito deletesull'affermazione sul proprio blog, Comprensione dell'eliminazione . È altamente raccomandato.


47
Controllato, funziona anche con "delete myJSONObject ['regex'];" Vedi: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok

110
Un risultato di una delle osservazioni al link "comprensione cancella" sopra, è che, poiché non è possibile eliminare necessariamente una variabile, ma solo le proprietà dell'oggetto, non è quindi possibile eliminare una proprietà dell'oggetto "per riferimento" - var value = obj [ 'puntello']; elimina valore // non funziona
Dexygen

27
Quindi in realtà non lo elimina? Diventa semplicemente indefinito, ma la chiave esiste ancora? Mi sto perdendo qualcosa?
Doug Molineux,

152
@Pete no, lo rimuove. Dato: var x = {a : 'A', b : 'B'};confronta: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */ax.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf il

16
@ChristopherPfohl lavora per me. Come ho detto, in realtà è abbastanza approfondito, quindi è un po 'difficile da riassumere. La risposta di base nella risposta sopra è sufficiente per quasi tutti i casi, il blog esamina alcuni dei casi limite e le ragioni per cui tali casi esistono.
Nickf

953

Gli oggetti in JavaScript possono essere pensati come mappe tra chiavi e valori. L' deleteoperatore viene utilizzato per rimuovere queste chiavi, più comunemente note come proprietà degli oggetti, una alla volta.

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

L' deleteoperatore non libera direttamente la memoria e differisce dalla semplice assegnazione del valore di nullo undefineda una proprietà, in quanto la proprietà stessa viene rimossa dall'oggetto. Nota che se il valore di una proprietà cancellata era un tipo di riferimento (un oggetto) e un'altra parte del tuo programma contiene ancora un riferimento a quell'oggetto, quell'oggetto, ovviamente, non sarà spazzato via fino a quando tutti i riferimenti ad esso hanno scomparso.

delete funzionerà solo su proprietà il cui descrittore li contrassegna come configurabili.


43
una proprietà assegnata a undefined è comunque una proprietà di un oggetto, quindi non verrà rimossa da GC, a meno che non venga letto male il tuo ultimo paragrafo.
Lance

8
Ho sbagliato a toccare il tema di GC qui. Entrambi i metodi hanno lo stesso risultato per GC: rimuovono il valore collegato alla chiave. Se quel valore fosse l'ultimo riferimento ad un altro oggetto, quell'oggetto verrebbe ripulito.
Dan

15
una proprietà assegnata a indefinito è ancora una proprietà di un oggetto, quindi non verrà rimossa da GC. Il GC non gestisce nulla sulle proprietà. Raccoglie e rimuove i valori. Finché nulla fa più riferimento a un valore (un oggetto, una stringa, ecc.), Il GC lo rimuove dalla memoria.
meandre,

8
A proposito, questo è il doppio problema per verificare se esiste una proprietà sull'oggetto Javascript. L'utilizzo nell'operatore è affidabile ma lento. Controlla se la proprietà non è indefinita "non è la risposta corretta" ma è molto più veloce. check
rdllopes,

8
Questa risposta è ancora pertinente? jsperf è attualmente in calo, ma questo benchmark sembra indicare che la differenza di velocità è solo del 25%, che non è in alcun modo vicino al "~ 100 volte più lento" in questa risposta.
Cerbrus,

248

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

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

Funziona in Firefox e Internet Explorer e penso che funzioni in tutti gli altri.


216

L' deleteoperatore viene utilizzato per rimuovere proprietà dagli oggetti.

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

Si noti che, per gli array, ciò non equivale alla rimozione di un elemento . Per rimuovere un elemento da un array, utilizzare Array#spliceo Array#pop. Per esempio:

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

Dettagli

deletein JavaScript ha una funzione diversa da quella della parola chiave in C e C ++: non libera direttamente la memoria. Invece, il suo unico scopo è rimuovere le proprietà dagli oggetti.

Per gli array, l'eliminazione di una proprietà corrispondente a un indice crea un array sparse (ovvero un array con un "buco" al suo interno). La maggior parte dei browser rappresenta questi indici di array mancanti come "vuoti".

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

Si noti che deletenon si trasferisce array[3]in array[2].

Diverse funzioni integrate in JavaScript gestiscono le matrici sparse in modo diverso.

  • for...in salterà completamente l'indice vuoto.

  • forVerrà restituito un ciclo tradizionale undefinedper il valore nell'indice.

  • Qualsiasi metodo utilizzato Symbol.iteratorrestituirà undefinedil valore nell'indice.

  • forEach, mapE reducesarà semplicemente ignorare l'indice mancante.

Pertanto, l' deleteoperatore non deve essere utilizzato per il caso d'uso comune di rimozione di elementi da un array. Gli array dispongono di metodi dedicati per la rimozione di elementi e la riallocazione della memoria: Array#splice()e Array#pop.

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

Array#splicemuta l'array e restituisce tutti gli indici rimossi. deleteCountgli elementi vengono rimossi dall'indice starte item1, item2... itemNinseriti nell'array dall'indice start. Se deleteCountviene omesso, gli elementi da startIndex vengono rimossi fino alla fine dell'array.

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

C'è anche un nome simile, ma diverso, funzione Array.prototype: Array#slice.

Array # slice ([inizio [, fine]])

Array#slicenon è distruttivo e restituisce un nuovo array contenente gli indici indicati da starta end. Se endnon specificato, viene impostato automaticamente alla fine dell'array. Se endè positivo, specifica l' indice non inclusivo in base zero a cui fermarsi. Se endè negativo, specifica l'indice a cui fermarsi contando alla fine dell'array (es. -1 ometterà l'indice finale). Se end <= start, il risultato è un array vuoto.

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#poprimuove l'ultimo elemento da un array e restituisce quell'elemento. Questa operazione modifica la lunghezza dell'array.


12
Questo approccio non modifica l'oggetto originale che potrebbe essere ancora referenziato altrove. Questo potrebbe o non potrebbe essere un problema a seconda di come viene utilizzato, ma è qualcosa da tenere a mente.
Tamas Czinege,

19
@ B1KMusic Ecco il modo di eliminare un elemento da un array: splice
wulftone

3
@wulftone no, che divide l'array e non fa nulla per eliminare un valore. Penso davvero che il modo migliore per eliminare da un array in cui siano necessari valori specifici da eliminare sia quello di utilizzare deletee creare una funzione Garbage Collection per ripulirlo.
Braden Best,

5
Non vedo splicenella tua modifica, ma removedovrebbe essereArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-

1
Questo articolo è pieno di tori 1. Non affronta la domanda! 2. È un abuso esemplificativo del linguaggio e si lamenta che "non funziona!" 3. Non incolpare l' operatore di eliminazione JavaScript per l'errore idiosincratico di Crockford di mettere null per un indice di array vuoto. Non capisce il significato di null - pensa che sia un errore. L'errore è suo e solo: non esiste un valore nullo nel valore eliminato di un determinato indice di array. Non esiste un "buco" nell'array: si tratta di un indice vuoto. Assolutamente legittimo e atteso.
Bekim Bacaj,

195

Vecchia domanda, risposta moderna. Utilizzando la distruzione degli oggetti, una funzione ECMAScript 6 , è semplice come:

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

O con l'esempio delle domande:

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

Puoi vederlo in azione nell'editor di prova Babel.


Modificare:

Per riassegnare alla stessa variabile, utilizzare a let:

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

6
Forse perché l'obiettivo è rimuovere una proprietà da un oggetto, non crearne una nuova senza la proprietà ... sebbene, la tua soluzione sia la mia preferita, poiché preferisco il modo immutabile.
Vingt_centimes,

8
La domanda diceva "per finire con il nuovo myObject".
Koen.

1
L'aggiunta di sottolineatura per la rimozione di una volontà cucciolata di proprietà del progetto :) Invece di avere a disposizione, come regexsi potrebbe anche assegnarlo a qualsiasi altra variabile, ad esempio _, quello che viene utilizzato in linguaggi come Go di scartare il risultato: const { regex: _, ...newObject } = myObject;.
Koen.

2
@PranayKumar Speravo che questa sintassi funzionasse; const { [key], ...newObject } = myObject;ma non lo è, quindi non credo sia possibile con la destrutturazione.
Koen.

2
Con freeze()'d e seal()' d oggetti, non puoi semplicemente deleteuna proprietà. Quindi questa è un'ottima alternativa. Anche se nella maggior parte dei casi, probabilmente non ha senso eliminare una proprietà da un oggetto congelato / sigillato, considerando che il punto è fornire alcune garanzie sulle strutture dei dati, di cui questo modello sarebbe minato. Per quei casi in cui è necessario ingannare in modo non distruttivo un oggetto ma senza alcune delle sue proprietà, questo è perfetto
Braden Best

119

Sintassi diffusa (ES6)

A chiunque ne abbia bisogno ...

Per completare la risposta di @Koen in questo thread, nel caso in cui desideri rimuovere la variabile dinamica utilizzando la sintassi di diffusione, puoi farlo in questo modo:

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

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

* foosarà una nuova variabile con il valore di a(che è 1).


RISPOSTA ESTESA 😇
Esistono pochi modi comuni per rimuovere una proprietà da un oggetto.
Ognuno ha i suoi pro e contro ( controlla questo confronto delle prestazioni ):

Elimina operatore
Leggibile e breve, tuttavia, potrebbe non essere la scelta migliore se si opera su un numero elevato di oggetti poiché le prestazioni non sono ottimizzate.

delete obj[key];


Riassegnazione
Più di 2 volte più veloce didelete, tuttavia la proprietànonvieneeliminata e può essere ripetuta.

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


Operatore di diffusione
QuestoES6operatore ci consente di restituire un oggetto nuovo di zecca, escludendo qualsiasi proprietà, senza mutare l'oggetto esistente. Il rovescio della medaglia è che ha le prestazioni peggiori rispetto a quanto sopra e non è consigliabile utilizzarlo quando è necessario rimuovere molte proprietà alla volta.

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

2
Penso che la sintassi spread / rest per i letterali di oggetti sia stata inclusa solo in ES2018 (ES9), non in ES6, anche se diversi motori JS l'avevano già implementata.
trincot

2
@trincot È stato introdotto per la prima volta nel 2014 ( github.com/tc39/proposal-object-rest-spread ) ed è una funzionalità ES6 (ECMAScript 2015 aka ECMAScript 6th Edition). Tuttavia, anche se sbaglio, non penso che faccia la differenza nel contesto della risposta.
Lior Elrom il

2
Il collegamento si riferisce a ES6, dove in effetti è stata introdotta la sintassi di diffusione per gli array, ma poi continua a proporre qualcosa di simile per i letterali di oggetti. Quella seconda parte è stata incorporata in ES9 solo se non sbaglio.
trincot

98

Un'altra alternativa è utilizzare la libreria Underscore.js .

Si noti che _.pick()e _.omit()sia il ritorno di una copia dell'oggetto e non modificare direttamente l'oggetto originale. Assegnare il risultato all'oggetto originale dovrebbe fare il trucco (non mostrato).

Riferimento: link _.pick (oggetto, * chiavi)

Restituisce una copia dell'oggetto, filtrato per avere solo valori per le chiavi della whitelist (o array di chiavi valide).

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

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

Riferimento: link _.omit (oggetto, * chiavi)

Restituisce una copia dell'oggetto, filtrata per omettere le chiavi nella lista nera (o array di chiavi).

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

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

Per matrici _.filter()e _.reject()può essere utilizzato in modo simile.


4
Tieni presente che se le chiavi del tuo oggetto sono numeri, potrebbe essere necessario_.omit(collection, key.toString())
Jordan Arseno,

Hmmmmm .... Il carattere di sottolineatura è ~ 100x più lento di quello delete obj[prop]che ~ 100x più lento di obj[prop] = undefined.
Jack Giffin,

52

Il termine che hai usato nel titolo della domanda Remove a property from a JavaScript object, può essere interpretato in diversi modi. L'uno è di rimuoverlo per tutta la memoria e l'elenco delle chiavi dell'oggetto o l'altro è solo per rimuoverlo dal tuo oggetto. Come è stato menzionato in alcune altre risposte, la deleteparola chiave è la parte principale. Diciamo che hai il tuo oggetto come:

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

Se fate:

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

il risultato sarebbe:

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

Puoi eliminare quella chiave specifica dalle chiavi dell'oggetto come:

delete myJSONObject["regex"];

Quindi la chiave degli oggetti che utilizzi Object.keys(myJSONObject)sarebbe:

["ircEvent", "method"]

Ma il punto è se ti preoccupi della memoria e vuoi che l'intero oggetto venga rimosso dalla memoria, si consiglia di impostarlo su null prima di eliminare la chiave:

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

L'altro punto importante qui è fare attenzione agli altri riferimenti allo stesso oggetto. Ad esempio, se crei una variabile come:

var regex = myJSONObject["regex"];

Oppure aggiungilo come nuovo puntatore a un altro oggetto come:

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

Quindi, anche se lo rimuovi dal tuo oggetto myJSONObject, quell'oggetto specifico non verrà cancellato dalla memoria, poiché la regexvariabile ha myOtherObject["regex"]ancora i suoi valori. Quindi come potremmo rimuovere l'oggetto dalla memoria di sicuro?

La risposta sarebbe quella di eliminare tutti i riferimenti che hai nel tuo codice, puntare a quell'oggetto stesso e anche non usare le varistruzioni per creare nuovi riferimenti a quell'oggetto . Quest'ultimo punto riguardante le vardichiarazioni, è uno dei problemi più cruciali che di solito dobbiamo affrontare, perché l'uso delle varistruzioni impedirebbe la rimozione dell'oggetto creato.

Ciò significa che in questo caso non sarai in grado di rimuovere quell'oggetto perché hai creato la regexvariabile tramite varun'istruzione e se lo fai:

delete regex; //False

Il risultato sarebbe false, il che significa che la tua dichiarazione di eliminazione non è stata eseguita come previsto. Ma se non avessi creato quella variabile prima e avessi avuto solo myOtherObject["regex"]come ultimo riferimento esistente, avresti potuto farlo semplicemente rimuovendolo come:

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

In altre parole, un oggetto JavaScript viene ucciso non appena nel codice non è rimasto alcun riferimento a tale oggetto.


Aggiornamento: grazie a @AgentME:

L'impostazione di una proprietà su null prima di eliminarla non compie nulla (a meno che l'oggetto non sia stato sigillato da Object.seal e l'eliminazione non riesca. Di solito non è così se non si tenta specificamente).

Per ottenere maggiori informazioni su Object.seal: Object.seal ()


Ti sbagli: solo gli oggetti vengono passati per riferimento in JavaScript, quindi se myJSONObject.regexil valore è una stringa e lo assegni a qualche altro oggetto, l'altro oggetto ha una copia di questo valore.
Michał Perłakowski il

Hai ragione e questa è una citazione: "stare attenti agli altri riferimenti allo stesso oggetto".
Mehran Hatami,

43

ECMAScript 2015 (o ES6) è stato fornito con l' oggetto Reflect integrato . È possibile eliminare la proprietà dell'oggetto chiamando la funzione Reflect.deleteProperty () con l'oggetto target e la chiave della proprietà come parametri:

Reflect.deleteProperty(myJSONObject, 'regex');

che equivale a:

delete myJSONObject['regex'];

Ma se la proprietà dell'oggetto non è configurabile, non può essere eliminata né con la funzione deleteProperty né con l'operatore delete:

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

Object.freeze () rende tutte le proprietà dell'oggetto non configurabili (oltre ad altre cose). deletePropertyLa funzione (oltre all'operatore di eliminazione ) ritorna falsequando tenta di eliminare una delle sue proprietà. Se la proprietà è configurabile, viene restituita true, anche se la proprietà non esiste.

La differenza tra deletee deletePropertyè quando si utilizza la modalità rigorosa:

"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 ha più vantaggi, specialmente quando devi fare alcune cose funzionali. Ad esempio, è possibile assegnare la funzione di variabili, passare come argomento o l'uso apply, call, bindfunzioni ...
madox2

41

Supponiamo di avere un oggetto simile al seguente:

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

Eliminazione di una proprietà dell'oggetto

Se si desidera utilizzare l'intero staffarray, il modo corretto per farlo è quello di fare questo:

delete Hogwarts.staff;

In alternativa, puoi anche fare questo:

delete Hogwarts['staff'];

Allo stesso modo, la rimozione dell'intero array di studenti verrebbe effettuata chiamando delete Hogwarts.students;o delete Hogwarts['students'];.

Eliminazione di un indice di array

Ora, se si desidera rimuovere un singolo membro dello staff o uno studente, la procedura è leggermente diversa, poiché entrambe le proprietà sono array stessi.

Se conosci l'indice del tuo membro del personale, potresti semplicemente fare questo:

Hogwarts.staff.splice(3, 1);

Se non conosci l'indice, dovrai anche effettuare una ricerca nell'indice:

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

Nota

Sebbene tecnicamente sia possibile utilizzarlo deleteper un array, il suo utilizzo comporterebbe risultati errati quando si chiama ad esempio in Hogwarts.staff.lengthseguito. In altre parole, deleterimuoverebbe l'elemento, ma non aggiornerebbe il valore della lengthproprietà. L'uso deleterovinerebbe anche la tua indicizzazione.

Pertanto, quando si eliminano i valori da un oggetto, considerare sempre se si ha a che fare con le proprietà degli oggetti o se si hanno a che fare con i valori dell'array e scegliere la strategia appropriata in base a ciò.

Se vuoi sperimentare questo, puoi usare questo violino come punto di partenza.


Penso che dovresti sempre usare spliceun array invece di delete.
Joel Trauger,

@JoelTrauger: Questo è quello che sto dicendo ;-)
John Slegers,

Sì. Il mio commento è che deletenon dovrebbe nemmeno essere una cosa. È spliceciò che l'OP stava cercando.
Joel Trauger,

1
@JoelTrauger: come ho cercato di spiegare, deletedovrebbe essere usato per le proprietà degli oggetti e spliceper gli elementi dell'array.
John Slegers,

La giuntura è molto lenta. Mentre dovrebbe essere usato invece che deletesu array, sarebbe più saggio non creare alcun codice centrato su di esso.
Jack Giffin,

39

Utilizzando ES6:

(Operatore Destructuring + Spread)

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

Non penso che questa sia una funzionalità ES6, ma inclusa solo in ES9.
trincot

Quindi in realtà non stai usando ES6, mentre scrivi, ma ES9 ... ;-)
trincot

2
Questo non sta rimuovendo una proprietà da un oggetto ma creando un nuovo oggetto senza quella proprietà.
Jordi Nebot,



29

Per clonare un oggetto senza proprietà:

Per esempio:

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

E dobbiamo eliminare "a".

1. Con chiave prop esplicita:

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

2. Con chiave prop variabile:

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

3. Funzione freccia fredda 😎:

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

object = removePropery('a', object);

4. Per più proprietà

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

uso

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

O

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

1
Slick funzione freccia!
JSilv,

27

L'uso del metodo delete è il modo migliore per farlo, come da descrizione MDN, l'operatore delete rimuove una proprietà da un oggetto. Quindi puoi semplicemente scrivere:

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

L'operatore delete rimuove una determinata proprietà da un oggetto. Se la cancellazione viene eseguita correttamente, verrà restituito true, altrimenti verrà restituito false. Tuttavia, è importante considerare i seguenti scenari:

  • Se la proprietà che si sta tentando di eliminare non esiste, delete non avrà alcun effetto e restituirà true

  • Se esiste una proprietà con lo stesso nome sulla catena di prototipi dell'oggetto, quindi, dopo l'eliminazione, l'oggetto utilizzerà la proprietà dalla catena di prototipi (in altre parole, l'eliminazione ha solo un effetto sulle proprie proprietà).

  • Qualsiasi proprietà dichiarata con var non può essere eliminata dall'ambito globale o dall'ambito di una funzione.

  • Pertanto, delete non può eliminare alcuna funzione nell'ambito globale (se fa parte di una definizione di funzione o di una funzione (espressione).

  • Le funzioni che fanno parte di un oggetto (a parte l'
    ambito globale) possono essere eliminate con delete.

  • Qualsiasi proprietà dichiarata con let o const non può essere eliminata dall'ambito in cui sono state definite. Le proprietà non configurabili non possono essere rimosse. Ciò include le proprietà di oggetti incorporati come Math, Array, Object e le proprietà create come non configurabili con metodi come Object.defineProperty ().

Il frammento seguente fornisce un altro semplice esempio:

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

Per ulteriori informazioni e per vedere altri esempi, visitare il link seguente:

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


22

Un'altra soluzione, utilizzando 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);

Tuttavia, sarà mutare l'oggetto originale. Se si desidera creare un nuovo oggetto senza la chiave specificata, è sufficiente assegnare la funzione di riduzione a una nuova variabile, ad esempio:

(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

Questo post è molto vecchio e lo trovo molto utile, quindi ho deciso di condividere la funzione non impostata che ho scritto nel caso in cui qualcun altro veda questo post e pensi perché non è così semplice come nella funzione unset di PHP.

Il motivo per scrivere questa nuova unsetfunzione è mantenere l'indice di tutte le altre variabili in questa hash_map. Guarda il seguente esempio e vedi come l'indice di "test2" non è cambiato dopo aver rimosso un valore da 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"}

20

Ci sono molte buone risposte qui, ma voglio solo chiarire che quando si utilizza il comando Elimina per rimuovere una proprietà in JavaScript, è spesso consigliabile verificare prima se tale proprietà esiste per prevenire errori.

Per esempio

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

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

A causa della natura dinamica di JavaScript, ci sono spesso casi in cui semplicemente non sai se la proprietà esiste o no. Controllando se obj esiste prima che && si assicuri anche di non generare un errore a causa della chiamata della funzione hasOwnProperty () su un oggetto non definito.

Scusate se questo non si è aggiunto al vostro caso d'uso specifico, ma credo che questo sia un buon design da adattare durante la gestione degli oggetti e delle loro proprietà.


2
delete foo.bar funziona anche se la barra non esiste, quindi il tuo test è un po 'troppo, IMHO.
PhiLho,

@PhiLho che dipende da dove stai eseguendo JavaScript. In Node.js credo che ciò causi l'arresto anomalo del tuo server.
Willem,

2
delete foo.bar;genera un'eccezione solo se foo è falso o se sei in modalità rigorosa e foo è un oggetto con una proprietà bar non configurabile.
Macil,

Non ricordo l'esatto problema che ho avuto con questo, ma penso che il problema possa apparire quando il foo stesso non esiste e si tenta di eliminare la sua proprietà.
Willem,

Sì, è necessario verificare se esiste foo, altrimenti foo.bar genererà un'eccezione, ma non è necessario controllare l'esistenza della barra prima di eliminarla. Questa è la parte "troppo" del mio commento. :-)
PhiLho,

16

Usando ramda # dissoc otterrai un nuovo oggetto senza l'attributo regex:

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

Puoi anche usare altre funzioni per ottenere lo stesso effetto: ometti, scegli, ...


15

Prova il seguente metodo. Assegna il Objectvalore della proprietà a undefined. Quindi stringifyl'oggetto e parse.

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

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

console.log(myObject);


1
InoltreJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy il

12

Se si desidera eliminare una proprietà profondamente nidificata nell'oggetto, è possibile utilizzare la seguente funzione ricorsiva con il percorso della proprietà come secondo argomento:

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

Esempio:

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

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

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

Questa funzione funziona come un incantesimo, ma perché è necessario restituire true e restituire false? La mia versione del codice: codepen.io/anon/pen/rwbppY . La mia versione fallirà in ogni caso?
normale

@ witty2017 non fallirà. Il luogo in cui ho usato la funzione doveva anche verificare se la proprietà esiste già o meno. se la proprietà non esiste, restituirà false. Se trova la proprietà e la elimina, restituirà true.
Ayushgp,

8

Puoi semplicemente eliminare qualsiasi proprietà di un oggetto usando la deleteparola chiave.

Per esempio:

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

Per rimuovere qualsiasi proprietà, ad esempio key1, utilizzare la deleteparola chiave in questo modo:

delete obj.key1

Oppure puoi anche usare la notazione simile ad un array:

delete obj[key1]

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

L'affermazione di Dan secondo cui "elimina" è molto lenta e il benchmark da lui pubblicato è stato messo in dubbio. Quindi ho eseguito il test da solo in Chrome 59. Sembra che 'delete' sia circa 30 volte più lento:

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

Si noti che ho intenzionalmente eseguito più di una operazione di "eliminazione" in un ciclo di ciclo per ridurre al minimo l'effetto causato dalle altre operazioni.


7

Prendi in considerazione la creazione di un nuovo oggetto senza la "regex"proprietà perché l'oggetto originale potrebbe sempre fare riferimento a altre parti del programma. Quindi dovresti evitare di manipolarlo.

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

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

console.log(newMyObject);


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

Provalo con un browser moderno come Firefox, Chromium o Safari. E mi aspetto che funzioni anche con Edge.
ideaboxer,

In alternativa, se i tuoi clienti ti costringono a supportare browser obsoleti, potresti prendere in considerazione l'uso di TypeScript che traspila il tuo codice in sintassi legacy (+ ti offre il vantaggio della sicurezza del tipo statico).
ideaboxer,

7

Rimozione della proprietà in JavaScript

Ci sono molte diverse opzioni presentate in questa pagina, non perché la maggior parte delle opzioni sono sbagliate o perché le risposte sono duplicate, ma perché la tecnica appropriata dipende dalla situazione in cui ti trovi e dagli obiettivi delle attività che tu e / o tu la squadra sta cercando di soddisfare. Per rispondere in modo inequivocabile alla tua domanda, devi sapere:

  1. La versione di ECMAScript che stai prendendo di mira
  2. L'intervallo di tipi di oggetto su cui desideri rimuovere le proprietà e il tipo di nomi di proprietà che devi poter omettere (solo stringhe? Simboli? Riferimenti deboli mappati da oggetti arbitrari? Questi sono tutti tipi di puntatori di proprietà in JavaScript da anni ormai )
  3. L'etica / i modelli di programmazione che tu e il tuo team utilizzate. Preferisci approcci funzionali e la mutazione è verboten nella tua squadra o impieghi tecniche orientate agli oggetti mutanti nel selvaggio west?
  4. Stai cercando di raggiungere questo obiettivo in puro JavaScript o sei disposto e in grado di utilizzare una libreria di terze parti?

Dopo aver risposto a queste quattro query, ci sono essenzialmente quattro categorie di "rimozione di proprietà" in JavaScript tra cui scegliere per raggiungere i tuoi obiettivi. Loro sono:

Cancellazione delle proprietà degli oggetti mutativi, non sicura

Questa categoria è destinata al funzionamento su valori letterali o istanze oggetto quando si desidera conservare / continuare a utilizzare il riferimento originale e non si utilizzano principi funzionali senza stato nel codice. Un esempio di sintassi in questa categoria:

'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

Questa categoria è la categoria di rimozione delle proprietà più antica, semplice e ampiamente supportata. Supporta Symbole indici di array oltre alle stringhe e funziona in ogni versione di JavaScript ad eccezione della prima versione. Tuttavia, è un mutativo che viola alcuni principi di programmazione e ha implicazioni sulle prestazioni. Inoltre, può comportare eccezioni non rilevate se utilizzato su proprietà non configurabili in modalità rigorosa .

Omissione della proprietà della stringa basata sul riposo

Questa categoria è per operare su istanze di oggetti semplici o array in versioni ECMAScript più recenti quando si desidera un approccio non mutativo e non è necessario tenere conto delle chiavi 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 :(

Cancellazione delle proprietà degli oggetti mutativi, sicura

Questa categoria è destinata al funzionamento su valori letterali o istanze oggetto quando si desidera conservare / continuare a utilizzare il riferimento originale mentre si protegge dalle eccezioni generate da proprietà non configurabili:

'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

Inoltre, mentre la mutazione degli oggetti sul posto non è stateless, è possibile utilizzare la natura funzionale di Reflect.deletePropertyeseguire un'applicazione parziale e altre tecniche funzionali che non sono possibili con le deleteistruzioni.

Omissione della proprietà della stringa basata sulla sintassi

Questa categoria è per operare su istanze di oggetti semplici o array in versioni ECMAScript più recenti quando si desidera un approccio non mutativo e non è necessario tenere conto delle chiavi 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 :(

Omissione di proprietà basata su libreria

Questa categoria generalmente consente una maggiore flessibilità funzionale, inclusa la contabilizzazione dei simboli e l'omissione di più di una proprietà in un'istruzione:

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"; elimina myObject [nome chiave];
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 Spiacente, non ho prestato attenzione a vedere quella risposta. Rispondo subito dopo aver visto delete myObject.regex;.
Xiang,

7

È possibile utilizzare la destrutturazione ES6 con l'operatore di riposo.

Le proprietà possono essere rimosse usando la destrutturazione in combinazione con l' operatore di riposo . Nel tuo esempio regex viene distrutto (ignorato) e il resto delle proprietà viene restituito come resto.

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

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

Oppure puoi escludere dinamicamente proprietà come questa,

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

Possiamo rimuovere qualsiasi proprietà da un oggetto javascript usando quanto segue:

  1. elimina object.property
  2. elimina oggetto ['proprietà']

esempio:

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.