javascript-objects class - Come rimuovere una proprietà da un oggetto JavaScript?




new add (25)

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

Answers

L'utilizzo 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. In caso di cancellazione riuscita, verrà restituito true, altrimenti verrà restituito false. Tuttavia, è importante considerare i seguenti scenari:

  • Se la proprietà che stai tentando di eliminare non esiste, elimina non avrà alcun effetto e restituirà true

  • Se esiste una proprietà con lo stesso nome sulla catena di prototipi dell'oggetto, dopo l'eliminazione, l'oggetto utilizzerà la proprietà dalla catena di prototipi (in altre parole, elimina solo ha 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ò cancellare alcuna funzione nell'ambito globale (se questo è 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 cancellata dall'ambito entro il quale sono state definite. Le proprietà non configurabili non possono essere rimosse. Ciò include le proprietà di oggetti built-in come Math, Array, Object e proprietà che vengono creati come non configurabili con metodi come Object.defineProperty ().

Il seguente frammento fornisce un altro semplice esempio:

var Employee = {
      age: 28,
      name: 'abc',
      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 maggiori informazioni e per vedere altri esempi, visita il link sottostante:

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


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;

Rimozione di 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 voi squadra stanno cercando di soddisfare. Per rispondere in modo inequivocabile alla domanda, è necessario sapere:

  1. La versione di ECMAScript che hai scelto come target
  2. L'intervallo di tipi di oggetto su cui vuoi rimuovere le proprietà e il tipo di nomi di proprietà che devi essere in grado di omettere (Solo stringhe? Simboli? Riferimenti deboli mappati da oggetti arbitrari? Questi sono stati tutti tipi di puntatori di proprietà in JavaScript per anni ora )
  3. L'ethos / schemi di programmazione utilizzati da te e dal tuo team. Preferite approcci funzionali e la mutazione è verboten sulla vostra squadra, o utilizzate tecniche orientate agli oggetti mutanti wild 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 domande, ci sono essenzialmente quattro categorie di "rimozione delle proprietà" in JavaScript tra cui scegliere per raggiungere i tuoi obiettivi. Loro sono:

Cancellazione di proprietà oggetto mutative, non sicure

Questa categoria è per il funzionamento su letterali di oggetti o istanze di oggetti quando si desidera conservare / continuare a utilizzare il riferimento originale e non utilizzare principi di funzionamento 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 più antica, più diretta e più ampiamente supportata categoria di rimozione di proprietà. Supporta gli Symbolindici di array oltre alle stringhe e funziona in tutte le versioni di JavaScript, tranne che per la primissima versione. Tuttavia, è mutativo che viola alcuni principi di programmazione e ha implicazioni sulle prestazioni. Inoltre, può comportare eccezioni non rilevate se utilizzato su developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .

Omissione della proprietà stringa basata sul resto

Questa categoria serve a operare su istanze di oggetti semplici o di array nei nuovi sapori di ECMAScript quando si desidera un approccio non mutativo e non è necessario tenere conto delle chiavi dei simboli:

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 di proprietà di oggetti mutativi, sicura

Questa categoria è per il funzionamento su letterali di oggetti o istanze di oggetti quando si desidera conservare / continuare a utilizzare il riferimento originale mentre si protegge da eccezioni generate su 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 modifica degli oggetti sul posto non è stateless, è possibile utilizzare la natura funzionale Reflect.deletePropertydell'applicazione parziale e altre tecniche funzionali che non sono possibili con le deleteistruzioni.

Omissione della proprietà stringa basata sulla sintassi

Questa categoria serve a operare su istanze di oggetti semplici o di array nei nuovi sapori di ECMAScript quando si desidera un approccio non mutativo e non è necessario tenere conto delle chiavi dei simboli:

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 della proprietà basata su libreria

Questa categoria consente generalmente una maggiore flessibilità funzionale, inclusa la contabilità per i simboli e l'omissione di più di una proprietà in una dichiarazione:

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"

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

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

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.


Molto semplice:

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

delete myObject.regex;

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

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

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


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}

Se si desidera eliminare una proprietà profondamente annidata 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: {}}}

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


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

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


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à.


Ciao, puoi provare questo semplice tipo

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);

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.


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, la parola chiave delete è 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 la chiave degli oggetti che utilizza 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, poiché la variabile regex e myOtherObject["regex"] hanno ancora i loro valori. Quindi come possiamo rimuovere l'oggetto dalla memoria di sicuro?

La risposta sarebbe eliminare tutti i riferimenti presenti nel codice, puntare a tale oggetto e non utilizzare le istruzioni var per creare nuovi riferimenti a quell'oggetto . Questo ultimo punto relativo alle istruzioni var , è uno dei problemi più cruciali che ci troviamo di fronte, perché l'uso delle istruzioni var impedirebbe che l'oggetto creato venga rimosso.

Ciò significa che in questo caso non sarai in grado di rimuovere quell'oggetto perché hai creato la variabile regex tramite un'istruzione var , 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 prima non avevi creato quella variabile, e avevi solo myOtherObject["regex"] come ultimo riferimento esistente, avresti potuto farlo 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.

Aggiornamento: grazie a @AgentME:

L'impostazione di una proprietà su null prima di eliminarla non porta a nulla (a meno che l'oggetto non sia stato sigillato da Object.seal e l'eliminazione non abbia esito positivo. Di solito non è il caso, a meno che non si provi specificamente).

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


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.


ECMAScript 2015 (o ES6) è venuto con l' oggetto Reflect integrato . È possibile eliminare la proprietà dell'oggetto chiamando la funzione Reflect.deleteProperty() con l'oggetto di destinazione e la 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). deletePropertyfunzione (così come developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) restituisce falsequando tenta di cancellare una delle sue proprietà. Se la proprietà è configurabile, restituisce true, anche se la proprietà non esiste.

La differenza tra deleteed 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

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


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.


Utilizzando ES6:

(Operatore di Distruzione + Spread)

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


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


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, ...


Citando da w3schools :

La direttiva "use strict"

La direttiva "use strict" è nuova in JavaScript 1.8.5 (ECMAScript versione 5).

Non è un'affermazione, ma un'espressione letterale, ignorata dalle precedenti versioni di JavaScript.

Lo scopo di "use strict" è indicare che il codice deve essere eseguito in "strict mode".

Con la modalità rigorosa, non è possibile, ad esempio, utilizzare variabili non dichiarate.

Perché la modalità rigorosa?

La modalità rigorosa semplifica la scrittura di JavaScript "sicuro".

La modalità rigorosa modifica la "sintassi errata" precedentemente accettata in errori reali.

Ad esempio, in JavaScript normale, l'errata digitazione di un nome di variabile crea una nuova variabile globale. In modalità rigorosa, questo genera un errore, rendendo impossibile creare accidentalmente una variabile globale.

In JavaScript normale, uno sviluppatore non riceverà alcuna risposta di errore che assegna valori a proprietà non modificabili.

In modalità rigorosa, qualsiasi assegnazione a una proprietà non scrivibile, una proprietà getter-only, una proprietà non esistente, una variabile non esistente o un oggetto non esistente genererà un errore.

Si prega di fare riferimento a http://www.w3schools.com/js/js_strict.asp per saperne di più





javascript javascript-objects object-properties