array - new object javascript




Come rimuovere una proprietà da un oggetto JavaScript? (20)

2 (ES6)

A chi ne ha bisogno ...

Per completare la risposta @Koen in questo thread, nel caso in cui desideri rimuovere una 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(rest); // { b: 2, c: 3 }

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


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

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
leggibile e breve, tuttavia potrebbe non essere la scelta migliore se si opera su un numero elevato di oggetti poiché le sue prestazioni non sono ottimizzate.

delete obj[key];


Reassignment
Più di 2 volte più veloce didelete, tuttavia la proprietànonvienecancellata e può essere iterata.

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


Spread Operator
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 peggiori prestazioni di cui sopra e non suggerito per essere utilizzato quando è necessario rimuovere molte proprietà alla volta.

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

Diciamo che creo un oggetto come segue:

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

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

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

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


L' delete dell'operatore è inaspettatamente lenta!

Guarda il benchmark .

Elimina è l'unico vero modo per rimuovere le proprietà dell'oggetto senza alcun avanzo, ma funziona ~ 100 volte più lentamente , rispetto alla sua "alternativa", impostando l' 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 in loop e hai problemi con le prestazioni, leggi la spiegazione dettagliata.

Quando si dovrebbe 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".

Usa 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).

Elimina la chiave dall'hashmap .

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

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

La chiave rimane nella sua posizione nell'hashmap , solo il valore viene sostituito con undefined . Capisci, che for..in loop continuerà a scorrere su quella chiave.

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

Utilizzando questo metodo, non tutti i modi per determinare l'esistenza della proprietà funzioneranno come previsto.

Tuttavia, questo codice:

object.field === undefined

si comporterà in modo equivalente per entrambi i metodi.

test

Per riassumere, le differenze riguardano esclusivamente i modi di determinare l'esistenza della proprietà e circa per il ciclo.

 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!

Mentre si usa obj[prop] = undefined è più veloce di fare delete obj[prop] , un'altra importante considerazione è che obj[prop] = undefined potrebbe non essere sempre appropriato. delete obj[prop] rimuove il prop da obj e lo cancella dalla memoria mentre obj[prop] = undefined imposta semplicemente il valore di prop a undefined che lascia il prop ancora in memoria. Pertanto, in circostanze in cui sono state create e cancellate molte chiavi, l'uso di obj[prop] = undefined può forzare una 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 ad eseguirlo di nuovo, tranne con la seguente versione del codice che utilizza invece l'operatore di delete .

"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 riportato, ci sono alcuni rari casi d'uso appropriati per l'operatore di delete . 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 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 l'operazione di delete ? 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 non bar[1] = undefined . 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 il valore vuoto o false o undefined . 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 valore vuoto. Si noti che internamente ci sono due tipi di numeri: numeri interi veloci (da 2147483647 a -2147483648 inclusi) e doppi in virgola mobile (qualsiasi cosa diversa da quella che include 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 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.


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 leggerne di più, l'utente di kangax ha scritto un post sul blog incredibilmente approfondito kangax delete sul proprio blog, Understanding delete . È altamente raccomandato


Prova questo

delete myObject['key'];

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

Notare che _.pick() e _.omit() restituiscono entrambi una copia dell'oggetto e non modificano 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, filtrata per avere solo i valori per le chiavi autorizzate (o una serie 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 in ​​blacklist (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() possono essere utilizzati in modo simile.


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. Utilizzare invece Array.prototype.splice .

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, inclusi gli array . Quindi, ritengo necessario segnalare un avvertimento particolare.

Nelle matrici, a differenza dei semplici vecchi oggetti, l'uso di delete lascia la spazzatura sotto forma di null , creando un "buco" nell'array.

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

Come puoi vedere, l' delete non funziona sempre come previsto. Il valore viene sovrascritto, ma la memoria non viene riallocata. Vale a dire, array[4] non è trasferito array[3] . Che è in contrasto con Array.prototype.unshift , che inserisce un elemento all'inizio dell'array e sposta tutto in alto ( array[0] diventa array[1] , ecc.)

Onestamente, a parte impostare su null invece che undefined - che è legittimamente strano - questo comportamento non dovrebbe sorprendere, dato che delete è un operatore unario, come typeof , che è hard-boiled nella lingua e non dovrebbe preoccuparsi sul tipo di oggetto su cui viene utilizzato, mentre Array è una sottoclasse di Object con metodi specificamente progettati per lavorare con gli array. Quindi non c'è una buona ragione per delete di avere 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, mi ha sorpreso. Perché l'ho scritto per giustificare la mia crociata contro la "spazzatura nulla":

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

Che è una terribile giustificazione per sbarazzarsi del null - 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 bug.

Quello che segue è uno scenario artificioso che diventa piuttosto prolisso, quindi puoi saltare alla sezione The Solution , 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é ... ragioni .

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

Scenario sempre più stupido a caso limite, l'uso delete su detto array comporterà il nullinquinamento dell'array e probabilmente causerà bug nell'app in seguito. E se controlli null , salterà direttamente 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, è possibile mantenere un secondo iteratore, come j , per incrementare solo quando i valori validi vengono letti dall'array. Ma questo non risolverà esattamente il problema null , e devi ancora piacere a quell'utente del troll PDP-11. Purtroppo, il suo computer non ha abbastanza memoria per contenere l'ultimo numero 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, gli array hanno un metodo specializzato per l'eliminazione degli indici e la riallocazione della 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() la matrice e restituisce gli indici rimossi. L'array viene tagliato a partire dall'indice, l' start e gli elementi n vengono suddivisi. Se n non è specificato, l'intero array dopo l' start viene 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 (inizio, fine)

.slice() non è distruttivo e restituisce un nuovo array contenente gli indici indicati start alla end . Se end viene lasciato non specificato, il comportamento è lo stesso di .splice() ( end = array.length ). Il comportamento è un po 'complicato dal momento che, per qualche motivo, gli indici di end da 1 invece di 0. Non so perché lo fa, ma è così che è. 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 per end è semplicemente escluso dalla sezione. 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 in modo che una funzione wrapper .splice() 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 è disattivato. Ciò include mettere una stringa come "3" . È lasciato al programmatore essere diligente riguardo ai suoi tipi. Questo per incoraggiare buone pratiche di programmazione.

Aggiornamento su 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 cioè 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 utilizzare la mia funzione is_array() , 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() . Usa let e const . Usa le nuove funzionalità che vengono aggiunte alla lingua. Non utilizzare i prefissi dei fornitori. Elimina quella cacca di polyfill IE dal tuo sito web. Elimina XHTML <!CDATA[[... crap, anche noi ci siamo spostati su HTML5 nel 2014. Prima tutti ritirano il supporto per quei browser vecchi / esoterici, prima i produttori di browser seguiranno effettivamente lo standard web e abbracceranno il nuova tecnologia, e prima potremo passare a un Web più sicuro.


Ci sono molte buone risposte qui, ma voglio solo sottolineare che quando si usa delete per rimuovere una proprietà in JavaScript, è spesso saggio verificare innanzitutto se esiste una proprietà 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 si sa se la proprietà esiste o meno. Verificare se obj esiste prima che && assicuri di non generare un errore dovuto alla chiamata della funzione hasOwnProperty () su un oggetto non definito.

Scusa se questo non è stato aggiunto al tuo caso d'uso specifico, ma ritengo che questo sia un buon progetto per adattarsi quando gestisci gli oggetti e le loro proprietà.


Molto semplice:

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

delete myObject.regex;

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

La ragione 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"}

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 si desidera utilizzare l'intero staffarray, 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;odelete 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 si può usare deleteper un array, utilizzarlo comporterebbe ottenere risultati errati quando si chiama per esempio in Hogwarts.staff.lengthseguito. In altre parole, deleterimuoverebbe l'elemento, ma non aggiornerebbe il valore della lengthproprietà. L'utilizzo deletepotrebbe anche rovinare 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 Fiddle come punto di partenza.


Usando il lodash

import omit from 'lodash/omit';

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

Usando Ramda

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

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.


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

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

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



L'affermazione di Dan secondo cui "cancellare" è molto lenta e il benchmark che ha pubblicato è stato messo in dubbio. Quindi ho eseguito il test da solo su Chrome 59. Sembra che "cancella" 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 effettuato intenzionalmente più di una operazione di "cancellazione" in un ciclo ad anello per minimizzare l'effetto causato dalle altre operazioni.


Personalmente uso Underscore.js per manipolazione di oggetti e array:

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

Prendi in considerazione la possibilità di creare un nuovo oggetto senza la "regex"proprietà perché l'oggetto originale potrebbe sempre essere referenziato da altre parti del tuo programma. Quindi dovresti evitare di manipolarlo.

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

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

console.log(newMyObject);


Puoi semplicemente cancellare 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 come segue:

delete obj.key1

Oppure puoi anche usare la notazione array-like:

delete obj[key1]

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


Un'altra soluzione, usando 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 vuoi creare un nuovo oggetto senza la chiave specificata, assegna semplicemente 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);





object-properties