Domanda Come rimuovere una proprietà da un oggetto JavaScript?


Diciamo che creo un oggetto come segue:

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

Qual è il modo migliore per rimuovere la proprietà regex per finire con nuovo myObject come segue?

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

4889
2017-10-16 10:57


origine


risposte:


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 leggere di più, utente Stack Overflow kangax  ha scritto un post sul blog incredibilmente approfondito su delete dichiarazione sul loro blog, Capire cancellare . È altamente raccomandato


6814
2017-10-16 10:58



Operatore delete è inaspettatamente lento!

Guarda al segno di riferimento .

Elimina è l'unico vero modo per rimuovere le proprietà dell'oggetto senza alcun avanzo, ma funziona ~ 100 volte più lento , rispetto alla sua "alternativa", impostazione object[key] = undefined.

Questa alternativa non è la risposta corretta a questa domanda! Ma, se lo usi con cura, puoi velocizzare notevolmente alcuni algoritmi. Se stai usando delete nei cicli e hai problemi con le prestazioni, leggi la spiegazione dettagliata.

Quando si dovrebbe usare delete e quando si imposta il valore su undefined ?

Un oggetto può essere visto come un insieme di coppie chiave-valore. Quello che chiamo un "valore" è un primitivo o un riferimento ad un altro oggetto, collegato a quella "chiave".

Uso delete,  quando passi l'oggetto risultato al codice su cui non hai il controllo (o quando non sei sicuro della tua squadra o te stesso).

esso elimina la chiave dall'hashmap .

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

Usa impostazione su undefined,  quando ti interessi delle prestazioni. Può dare un forte impulso al tuo codice.

Il la chiave rimane nella sua posizione nell'hashmap , solo il valore è sostituito con undefined. Capire che for..in il ciclo continuerà a scorrere su quella chiave.

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

Usando questo metodo, non tutti modi per determinare l'esistenza della proprietà  funzionerà come previsto

Tuttavia, questo codice:

object.field === undefined

si comporterà in modo equivalente per entrambi i metodi.

test

Per riassumere, le differenze riguardano tutti i modi di determinare l'esistenza della proprietà, e circa for..in ciclo continuo.

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

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

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

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

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

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

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

Attenzione alle perdite di memoria!

Durante l'utilizzo obj[prop] = undefined è più veloce del fare delete obj[prop], un'altra considerazione importante è quella obj[prop] = undefined potrebbe non essere sempre appropriato delete obj[prop] rimuove prop a partire dal obj e lo cancella dalla memoria mentre obj[prop] = undefined imposta semplicemente il valore di prop a undefined che lascia prop ancora in memoria. Pertanto, nelle circostanze in cui sono state create e cancellate molte chiavi, utilizzando obj[prop] = undefined può forzare la costosa riconciliazione della memoria (causando il blocco della pagina) e potenzialmente un errore di memoria insufficiente. Esamina il seguente codice.

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

Nel codice sopra, semplicemente facendo nodeRecords[i][lastTime] = undefined; causerà una perdita di memoria enorme perché ogni frame di animazione. Ogni frame, tutti i 65536 elementi DOM occuperanno altri 65536 singoli slot, ma i precedenti 65.536 slot saranno impostati su undefined che li lascerà in memoria. Vai avanti, prova a eseguire il codice sopra nella console e vedere di persona. Dopo aver forzato un errore di memoria esaurita, provare a eseguirlo di nuovo tranne con la seguente versione del codice che utilizza il file deleteoperatore invece.

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

Come visto nello snippet di codice sopra, ci sono alcuni rari casi d'uso appropriati per il delete operatore. Tuttavia, non preoccuparti troppo di questo problema. Questo diventerà solo un problema con oggetti a durata prolungata che aggiungono costantemente nuove chiavi. In ogni altro caso (che è quasi ogni caso nella programmazione del mondo reale), è più appropriato da usare obj[prop] = undefined. Lo scopo principale di questa sezione è solo quello di portarlo alla tua attenzione in modo che nella rara possibilità che questo diventi un problema nel tuo codice, allora puoi capire più facilmente il problema e quindi non dover perdere ore a dissezionare il tuo codice per localizzarlo e capisco questo problema

Non sempre impostato su undefined

Un aspetto di Javascript che è importante considerare è il polimorfismo. Il polimorfismo si ha quando si assegnano gli stessi tipi di variabile / slot-in-un-oggetto diversi, come mostrato di seguito.

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

Tuttavia, ci sono due principali problemi non risolvibili con gli array polimorfici:

  1. Sono lenti e la memoria inefficiente. Quando si accede a un indice specifico, invece di ottenere il tipo globale per l'array, il browser deve invece ottenere il tipo su base indice per cui ogni indice memorizza i metadati aggiuntivi del suo tipo.
  2. Una volta polimorfico, sempre polimorfico. Quando un array viene reso polimorfico, il polimorfismo non può essere annullato nei browser Webkit. Quindi, anche se si ripristina un array polimorfico non polimorfo, esso verrà comunque memorizzato dal browser come array polimorfico.

Si può paragonare il polimorfismo a una dipendenza da droga. A prima vista, sembra incredibilmente redditizio: bel codice piuttosto soffice. Quindi, il codificatore introduce la matrice al farmaco del polimorfismo. Immediatamente, l'array polimorfico diventa meno efficiente e non può mai diventare efficiente come prima, dal momento che è drogato. Per mettere in relazione tale circostanza con la vita reale, qualcuno in cocaina potrebbe non essere nemmeno in grado di gestire una semplice maniglia della porta, e tanto meno essere in grado di calcolare le cifre di PI. Allo stesso modo, un array sul farmaco del polimorfismo non può mai essere efficiente come un array monomorfico.

Ma come si collega un'analogia di droga con il delete operazione? La risposta eredita l'ultima riga di codice nello snippet sopra. Quindi lascia che sia riesaminato, questa volta con una svolta.

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

Osservare. bar[1] = "" non costringe il polimorfismo mentre bar[1] = undefined lo fa. Pertanto, si dovrebbe sempre, quando possibile, usare il tipo corrispondente per i loro oggetti in modo da non provocare accidentalmente il polimorfismo. Una di queste persone può usare la seguente lista come riferimento generale per farle andare avanti. Tuttavia, ti preghiamo di non utilizzare esplicitamente le seguenti idee. Invece, usa quello che funziona bene per il tuo codice.

  • Quando si utilizza una matrice / variabile digitata sulla primitiva booleana, utilizzare entrambi false o undefined come il valore vuoto. Evitare il polimorfismo inutile è buono, riscrivere tutto il codice per proibire esplicitamente che probabilmente si tradurrà in una diminuzione delle prestazioni. Usa il giudizio comune!
  • Quando si utilizza una matrice / variabile digitata sulla primitiva del numero, utilizzare 0 come il valore vuoto. Nota che internamente ci sono due tipi di numeri: interi veloci (da 2147483647 a -2147483648 inclusi) e doppi in virgola mobile (qualsiasi cosa diversa da quella inclusa NaN e Infinity). Quando un intero è declassato a un doppio, non può essere promosso a un intero.
  • Quando si utilizza una matrice / variabile digitata sulla stringa primitiva, utilizzare "" come il valore vuoto.
  • Quando usi un simbolo, aspetta, perché stai usando un simbolo?!?! I simboli sono cattivi juju per le prestazioni. Tutto ciò che è programmato per utilizzare i Simboli può essere riprogrammato per non usare Simboli, risultando in un codice più veloce senza Simboli. I simboli sono in realtà solo super-inefficienti meta-zucchero.
  • Quando usi qualcos'altro, usa null.

Tuttavia, sii consapevole! Non iniziare improvvisamente a fare questo con tutti i tuoi codici preesistenti ora poichè probabilmente romperà questo codice preesistente e / o introdurrà bug strani. Piuttosto, una pratica così efficiente deve essere implementata fin dall'inizio, e quando si converte il codice preesistente, si consiglia di raddoppiare, triplicare, quadruplicare tutte le righe relative a questo come provare ad aggiornare il vecchio codice a questa nuova pratica può essere come rischioso in quanto è gratificante.


698
2018-02-12 17:48



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

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

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


192
2017-10-16 11:03



Aggiornamento 2018-07-21:  Per molto tempo, mi sono sentito imbarazzato per questa risposta, quindi penso che sia ora di rimuoverlo un po '. Solo un piccolo commento, chiarimento e formattazione per accelerare la lettura delle parti inutilmente lunghe e contorte di questa risposta.


LA VERSIONE BREVE

La vera risposta alla domanda

Come altri hanno già detto, puoi usare delete.

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

Equivalente di array

non delete da un array. Uso Array.prototype.splice anziché.

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

LA VERSIONE LUNGA

JavaScript è un linguaggio OOP, quindi tutto è un oggetto, incluso array . Quindi, ritengo necessario segnalare un avvertimento particolare.

Negli array, a differenza dei semplici vecchi oggetti, usando delete lascia la spazzatura sotto forma di null, creando un "buco" nella matrice.

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

Come potete vedere, delete non funziona sempre come ci si potrebbe aspettare. Il valore viene sovrascritto, ma la memoria non viene riallocata. Vale a dire, array[4] non è stato trasferito a array[3]. Che è in contrasto con Array.prototype.unshift, che inserisce un elemento all'inizio della matrice e sposta tutto in alto ( array[0] diventa array[1], eccetera.)

Onestamente, a parte l'impostazione null piuttosto che undefined- che è legittimamente strano - questo comportamento non dovrebbe  essere sorprendente, dal momento che delete è un operatore unario, come typeof, che è difficile da bollire nella lingua e non dovrebbe preoccuparsene genere  di oggetto su cui viene usato, mentre Array è una sottoclasse di Object con metodi specificamente progettato per  lavorando con gli array. Quindi non c'è una buona ragione per deleteavere un caso speciale cucinato per ri-spostare l'array, in quanto ciò rallenterebbe le cose con il lavoro non necessario. In retrospettiva, le mie aspettative non erano realistiche.

Certo che fatto  Sorprendimi. Perché l'ho scritto per giustificare la mia crociata contro la "spazzatura nulla":

Ignorando i pericoli e i problemi inerenti nulle lo spazio perso, questo può essere problematico se l'array deve essere preciso.

Quale è una terribile giustificazione per sbarazzarsi del nullS-- null è pericoloso solo se usato in modo improprio e non ha nulla a che fare con la "precisione". La vera ragione per cui non dovresti delete da un array è perché lasciare strutture di dati immondizie e disordinate intorno è sciatta e soggetta a errori.

Quello che segue è uno scenario artificioso che diventa piuttosto prolisso, quindi puoi saltare alla sezione, La soluzione , se vuoi. L'unica ragione per cui ho lasciato questa sezione è perché penso che alcune persone probabilmente pensano che sia divertente, e io non voglio essere "quel ragazzo" che pubblica una risposta "divertente" e poi cancella tutti i "divertenti" da esso in seguito .

... È stupido, lo so.

Lo scenario artificioso e prolisso di PDP-11

Ad esempio, supponiamo di creare una webapp che utilizza la serializzazione JSON per memorizzare una matrice utilizzata per "tab" in una stringa (in questo caso, localStorage). Diciamo anche che il codice usa gli indici numerici dei membri dell'array per "titolo" quando disegnano sullo schermo. Perché lo stai facendo piuttosto che archiviare anche il "titolo"? Perché... motivi .

Okay, diciamo che stai cercando di risparmiare memoria su richiesta di questo uno  utente che esegue un minicomputer PDP-11 degli anni '60 che esegue UNIX e ha scritto il proprio browser basato su Elinks, compatibile con JavaScript, compatibile con la linea perché X11 è fuori questione .

Scenario caso sempre più stupido a parte, usando delete su detto array risulterà null inquinando l'array e probabilmente causando bug nell'app in seguito. E se controlli null, salta dritto salta i numeri risultanti nelle schede che vengono visualizzate come [1] [2] [4] [5] ....

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

Sì, non è assolutamente quello che volevi.

Ora tu poteva  mantenere un secondo iteratore, come j, da incrementare solo quando i valori validi vengono letti dall'array. Ma questo non risolverebbe esattamente il null problema, e devi ancora compiacerlo troll  Utente PDP-11. Ahimè, il suo computer solo non lo fa  avere abbastanza memoria per contenere l'ultimo intero (non chiedere come riesce a gestire un array a larghezza variabile ...) .

Quindi, ti manda una mail con rabbia:

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

A questo punto, sei alla fine del tuo spirito. Questo ragazzo si è lamentato senza sosta della tua app, e tu vuoi dirgli di stare zitto e andare a prendere un computer migliore.

La soluzione: Array.prototype.splice

Fortunatamente, matrici fare  avere un metodo specializzato per cancellare gli indici e riallocare la memoria: Array.prototype.splice(). Potresti scrivere qualcosa come questo:

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

E proprio così, sei contento di Mr. PDP-11. Evviva! (Lo direi comunque, comunque ...)

Array.prototype.splice vs Array.prototype.slice

Ritengo sia importante sottolineare la differenza tra queste due funzioni con nomi simili, in quanto entrambe sono molto utili.

Array.prototype.splice (inizio, n)

.splice() muta l'array e restituisce gli indici rimossi. L'array viene tagliato a partire dall'indice, start, e n gli elementi sono tagliati. Se n non è specificato, l'intero array dopo start è affettato ( 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 (inizio, fine)

.slice() non è distruttivo e restituisce un nuovo array contenente gli indici indicati da start a end. Se end è lasciato non specificato, il comportamento è lo stesso di .splice() ( end = array.length). Il comportamento è un po 'complicato poiché, per qualche motivo, end indici da 1 invece di 0. Non so perché lo faccia, ma è così. Inoltre, se end <= start, il risultato è un array vuoto.

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]

Questo in realtà non è ciò che sta accadendo, ma è più facile pensare in questo modo. Secondo MDN, ecco cosa sta realmente accadendo:

// 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

L'indice specificato da end è semplicemente escluso dalla fetta. Gli indici tra parentesi indicano ciò che viene tagliato. In entrambi i casi, il comportamento non è intuitivo ed è destinato a causare la sua giusta quota di errori off-by-one, quindi potrebbe essere utile fare una funzione wrapper per emulare più da vicino il comportamento di .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]

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

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

Si noti che la funzione wrapper è progettata per essere molto rigida sui tipi e restituirà null se qualcosa è spento. Questo include mettere una stringa come "3". È lasciato al programmatore essere diligente riguardo ai suoi tipi. Questo per incoraggiare buone pratiche di programmazione.

Aggiornamento in merito is_array()

Questo è in relazione a questo frammento (ora rimosso):

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

Quindi, come risulta, esiste in realtà un modo integrato per dire se un array è veramente un array, e questo è vero Array.isArray(), introdotto in ECMAScript 5 (dicembre 2009). L'ho trovato mentre cercavo di vedere se c'era una domanda che chiedeva di dire agli array di oggetti, di vedere se c'era una soluzione migliore della mia o di aggiungere la mia se non ce n'erano. Quindi, se stai utilizzando una versione di JavaScript precedente all'ECMA 5, c'è il tuo polyfill. Tuttavia, consiglio vivamente di non usare il mio is_array() funzione, poiché continuare a supportare le vecchie versioni di JavaScript significa continuare a supportare i vecchi browser che li implementano, il che significa incoraggiare l'uso di software non sicuro e mettere gli utenti a rischio di malware. Quindi per favore, usa Array.isArray(). Uso let e const. Usa le nuove funzionalità che vengono aggiunte alla lingua. non  utilizzare i prefissi dei fornitori. Elimina  che IE polyfill fa schifo dal tuo sito web. Elimina quell'XHTML <!CDATA[[... crap, anche noi - ci siamo spostati su HTML5 nel 2014. Prima tutti ritirano il supporto per quei browser vecchi / esoterici, prima i venditori di browser seguiranno effettivamente lo standard web e accetteranno la nuova tecnologia, e prima potremo passare a un web più sicuro.


133
2017-09-18 00:56



Vecchia domanda, risposta moderna. Usando la destrutturazione di oggetti, a ECMAScript 6  caratteristica, è semplice come:

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

Oppure con il campione 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 di Babel.


Modificare:

Per riassegnare alla stessa variabile, utilizzare a let:

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

91
2017-11-08 18:02



Un'altra alternativa è usare il Underscore.js  biblioteca.

Nota che _.pick() e _.omit() entrambi restituiscono una copia dell'oggetto e non modificano direttamente l'oggetto originale. Assegnare il risultato all'oggetto originale dovrebbe fare il trucco (non mostrato).

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

Restituisce una copia dell'oggetto, filtrata per avere solo valori per il chiavi autorizzate (o serie di chiavi valide).

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

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

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

Restituisce una copia dell'oggetto, filtrata per omettere il chiavi in ​​lista nera (o array di chiavi).

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

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

Per gli array, _.filter() e _.reject() può essere utilizzato in modo simile.


65
2018-05-24 18:53



Il termine che hai usato nel titolo della tua domanda Remove a property from a JavaScript object, può essere interpretato in diversi modi. Il primo è 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 altre risposte, il delete la parola 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"]

È possibile eliminare quella chiave specifica dalle chiavi dell'oggetto come:

delete myJSONObject["regex"];

Quindi utilizzare i tuoi oggetti chiave Object.keys(myJSONObject) sarebbe:

["ircEvent", "method"]

Ma il punto è che se ti interessa la memoria e vuoi che l'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, dal momento che regex variabile e myOtherObject["regex"] hanno ancora i loro valori. Quindi come possiamo rimuovere l'oggetto dalla memoria di sicuro?

La risposta sarebbe cancella tutti i riferimenti che hai nel tuo codice, punta a quello stesso oggetto  e anche non usare var istruzioni per creare nuovi riferimenti a quell'oggetto . Questo ultimo punto riguardo var dichiarazioni, è uno dei problemi più cruciali che ci troviamo di fronte, perché l'uso var le istruzioni impedirebbero la rimozione dell'oggetto creato.

Ciò significa che in questo caso non sarai in grado di rimuovere quell'oggetto perché hai creato il regex variabile tramite a var dichiarazione, e se lo fai:

delete regex; //False

Il risultato sarebbe false, il che significa che la tua istruzione di cancellazione non è stata eseguita come previsto. Ma se non avessi creato quella variabile prima, e l'hai avuto solo tu 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 non vi è alcun riferimento lasciato nel codice puntato a quell'oggetto.


Aggiornare: Grazie a @AgentME:

L'impostazione di una proprietà su null prima di eliminarla non viene eseguita   qualsiasi cosa (a meno che l'oggetto non sia stato sigillato da Object.seal e il   elimina fallisce. Di solito non è questo il caso, a meno che tu non lo faccia specificamente   provare).

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


33
2018-02-12 06:29



ECMAScript 2015 (o ES6) è venuto con built-in Riflettere  oggetto. È possibile eliminare la proprietà dell'oggetto chiamando Reflect.deleteProperty ()  funzione con oggetto di destinazione e chiave di proprietà come parametri:

Reflect.deleteProperty(myJSONObject, 'regex');

che è equivalente a:

delete myJSONObject['regex'];

Ma se la proprietà dell'oggetto non è configurabile, non può essere cancellata né con 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). deleteProperty funzione (come pure cancella operatore ) ritorna false quando cerca di cancellare una delle sue proprietà. Se la proprietà è configurabile, restituisce true, anche se la proprietà non esiste.

La differenza tra delete e 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

28
2018-01-10 16:36



Supponiamo di avere un oggetto simile a questo:

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 vuoi usare l'intero staff array, il modo corretto per farlo, sarebbe 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 potrebbe essere 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 dello staff, puoi semplicemente fare questo:

Hogwarts.staff.splice(3, 1);

Se non conosci l'indice, dovrai anche fare una ricerca per indice:

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

Nota

Mentre tecnicamente puoi usare delete per un array, l'utilizzo di esso comporterebbe l'ottenimento di risultati errati durante la chiamata ad esempio Hogwarts.staff.length più tardi. In altre parole, delete rimuoverà l'elemento, ma non aggiornerebbe il valore di length proprietà. utilizzando delete rovinerebbe anche la tua indicizzazione.

Pertanto, quando si eliminano i valori da un oggetto, considerare sempre se si tratta di proprietà dell'oggetto o se si tratta di valori di array e scegliere la strategia appropriata in base a tale.

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


28
2018-02-21 18:09