Vraag Hoe verwijder ik een eigenschap uit een JavaScript-object?


Stel dat ik een object als volgt maak:

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

Wat is de beste manier om het eigendom te verwijderen? regex om met nieuw te eindigen myObject als volgt?

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

4893
2017-10-16 10:57


oorsprong


antwoorden:


Soortgelijk:

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

demonstratie

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

console.log(myObject);

Voor iedereen die geïnteresseerd is in meer informatie hierover, Stack Overflow-gebruiker kangax heeft een ongelooflijk diepgaande blogpost geschreven over de delete verklaring op hun blog, Inzicht in verwijderen. Het wordt sterk aanbevolen.


6817
2017-10-16 10:58



operator delete is onverwacht langzaam!

Kijk naar de criterium.

Verwijderen is de enige echte manier om objecteigenschappen te verwijderen zonder restjes, maar het werkt ~ 100 keer langzamer, vergeleken met zijn "alternatief", instelling object[key] = undefined.

Dit alternatief is niet het juiste antwoord op deze vraag! Maar als u het met zorg gebruikt, kunt u sommige algoritmen drastisch versnellen. Als je gebruikt delete in loops en je hebt problemen met de uitvoering, lees de uitgebreide uitleg.

Wanneer moet je gebruiken delete en wanneer waarde is ingesteld op undefined ?

Een object kan worden gezien als een set sleutel / waarde-paren. Wat ik een 'waarde' noem, is een primitieve of een verwijzing naar een ander object, verbonden met die 'sleutel'.

Gebruik delete, wanneer u het resultaatobject doorgeeft aan de code waarop u geen controle hebt (of wanneer u niet zeker bent over uw team of uzelf).

Het verwijdert de sleutel uit de hashmap.

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

Gebruik instelling om undefined, wanneer je om prestaties geeft. Het kan een serieuze boost geven aan uw code.

De sleutel blijft op zijn plaats in de hashmap, alleen de waarde wordt vervangen door undefined. Begrijp dat for..in loop herhaalt nog steeds die toets.

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

Met behulp van deze methode, niet alles manieren om het eigendomsbestaan ​​te bepalen zal werken zoals verwacht.

Deze code is echter:

object.field === undefined

zal zich voor beide methoden op dezelfde manier gedragen.

Tests

Samengevat: verschillen gaan allemaal over manieren om het bestaan ​​van het eigendom te bepalen, en over for..in lus.

 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. *');

Pas op voor geheugenlekken!

Tijdens het gebruik obj[prop] = undefined is sneller dan doen delete obj[prop], een andere belangrijke overweging is dat obj[prop] = undefined misschien niet altijd geschikt. delete obj[prop] verwijdert prop van obj en wist het uit het geheugen terwijl obj[prop] = undefined stelt eenvoudig de waarde in van prop naar undefined welke vertrekt prop nog steeds in het geheugen. Daarom, in omstandigheden waarin er veel sleutels worden gemaakt en verwijderd, gebruikt u obj[prop] = undefined kan dure geheugenafstemming forceren (waardoor de pagina bevriest) en mogelijk een fout die niet vol is. Bestudeer de volgende code.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

In de bovenstaande code gewoon doen nodeRecords[i][lastTime] = undefined; veroorzaakt een enorm geheugenlek omdat elk animatieframe. Voor elk frame nemen alle 65536 DOM-elementen nog eens 65536 afzonderlijke slots op, maar de vorige 65536-slots worden alleen ingesteld op undefined, waardoor ze in het geheugen blijven hangen. Ga je gang, probeer de bovenstaande code in de console uit te voeren en overtuig jezelf. Na het dwingen van een geheugenfout, probeert u het opnieuw uit te voeren, behalve met de volgende versie van de code die de deleteoperator in plaats daarvan.

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

Zoals te zien in het bovenstaande codefragment, zijn er enkele zeldzame geschikte gebruikscasussen voor de delete operator. Maak je echter niet te veel zorgen om dit probleem. Dit wordt alleen een probleem met objecten met een lange levensduur, waardoor er voortdurend nieuwe toetsen aan worden toegevoegd. In alle andere gevallen (wat bijna altijd het geval is bij real-world programmering), is het het meest geschikt om te gebruiken obj[prop] = undefined. Het belangrijkste doel van deze sectie is om dit onder uw aandacht te brengen, zodat u in de zeldzame kans dat dit een probleem wordt in uw code, het probleem gemakkelijker begrijpt en dus geen uren hoeft te besteden aan het ontleden van uw code om te lokaliseren en begrijp dit probleem.

Niet altijd instellen op undefined

Een aspect van Javascript dat belangrijk is om te overwegen, is polymorfisme. Polymorfisme is het toewijzen van dezelfde variabele / slot-in-een-object verschillende typen zoals hieronder te zien.

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

Er zijn echter twee belangrijke niet-oplosbare problemen met polymorfe arrays:

  1. Ze zijn traag en geheugen inefficiënt. Bij het benaderen van een specifieke index hoeft de browser in plaats van alleen het globale type voor de array te krijgen, het type per index te krijgen, waarbij elke index de aanvullende metagegevens van zijn type opslaat.
  2. Eenmaal polymorf, altijd polymorf. Wanneer een array polymorf is gemaakt, kan het polymorfisme niet ongedaan worden gemaakt in Webkit-browsers. Dus zelfs als u een polymorfe array herstelt als niet-polymorfisch, zal het nog steeds door de browser worden opgeslagen als een polymorfe array.

Men kan polymorfisme vergelijken met een drugsverslaving. Op het eerste gezicht lijkt het ontzettend lucratief: mooie, mooie, pluizige code. Vervolgens introduceert de codeerder zijn array aan het medicijn van polymorfisme. Onmiddellijk wordt de polymorfe array minder efficiënt en kan het nooit zo efficiënt worden als eerder omdat het is gedrogeerd. Om een ​​dergelijke omstandigheid te koppelen aan het echte leven, is iemand met cocaïne misschien niet eens in staat om een ​​eenvoudige deurgreep te bedienen, laat staan ​​om cijfers van PI te berekenen. Evenzo kan een array op het medicijn van polymorfisme nooit zo efficiënt zijn als een monomorfe array.

Maar, hoe verhoudt een drugsreis-analogie zich met de delete operatie? Het antwoord bevat de laatste regel code in het bovenstaande fragment. Laat het dus opnieuw worden bekeken, deze keer met een twist.

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

Observeren. bar[1] = "" dwingt polymorfisme niet af terwijl bar[1] = undefined doet. Daarom moet men altijd, indien mogelijk, het overeenkomstige type gebruiken voor hun objecten om niet per ongeluk polymorfisme te veroorzaken. Een dergelijke persoon kan de volgende lijst gebruiken als algemene verwijzing om ze op gang te krijgen. Gebruik de onderstaande ideeën echter niet expliciet. Gebruik in plaats daarvan alles wat goed werkt voor uw code.

  • Gebruik een array / variabele die is getypt in de boolean-primitief false of undefined als de lege waarde. Hoewel het vermijden van onnodig polymorfisme goed is, zal het herschrijven van al uw code om expliciet te verbieden, waarschijnlijk resulteren in een afname van de prestaties. Gebruik een gezond oordeel!
  • Gebruik als u een array / variabele gebruikt die is getypt naar het nummer primitief 0 als de lege waarde. Merk op dat er intern twee typen getallen zijn: snelle gehele getallen (2147483647 tot en met -2147483648) en langzame zwevende dukten (alles behalve dat inclusief NaN en Infinity). Als een geheel getal wordt gedegradeerd tot een verdubbeling, kan het niet opnieuw worden gepromoveerd tot een geheel getal.
  • Gebruik als u een array / variabele gebruikt die is getypt in de primitieve tekenreeks "" als de lege waarde.
  • Wanneer u een symbool gebruikt, wacht, waarom gebruikt u een symbool?!?! Symbolen zijn slechte juju voor prestaties. Alles wat is geprogrammeerd om symbolen te gebruiken, kan opnieuw worden geprogrammeerd om geen symbolen te gebruiken, wat resulteert in een snellere code zonder symbolen. Symbolen zijn eigenlijk gewoon super inefficiënte meta-suiker.
  • Gebruik bij gebruik van iets anders null.

Wees echter bedachtzaam! Begin dit niet plotseling te doen met al uw reeds bestaande code, omdat het waarschijnlijk zou breken met een dergelijke reeds bestaande code en / of vreemde bugs zou introduceren. Integendeel, zo'n efficiënte procedure moet vanaf het begin worden geïmplementeerd en bij het converteren van reeds bestaande code, is het aan te bevelen om alle regels die daarmee verband houden te verdubbelen, te verdubbelen, viermaal te controleren, omdat het proberen om oude code te upgraden naar deze nieuwe praktijk zo kan zijn als riskant omdat het lonend is.


700
2018-02-12 17:48



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

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

Dit werkt in Firefox en Internet Explorer en ik denk dat het in alle andere werkt.


192
2017-10-16 11:03



Update 2018-07-21: Ik heb me lange tijd gegeneerd gevoeld voor dit antwoord, dus ik denk dat het tijd is dat ik het een beetje opfris. Gewoon een beetje commentaar, verduidelijking en opmaak om het lezen van de onnodig lange en ingewikkelde gedeelten van dit antwoord te bespoedigen.


DE KORTE VERSIE

Het eigenlijke antwoord op de vraag

Zoals anderen al hebben gezegd, kunt u gebruiken delete.

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

Array-equivalent

doe niet delete van een array. Gebruik Array.prototype.splice in plaats daarvan.

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

DE LANGE VERSIE

JavaScript is een OOP-taal, dus alles is een object, inclusief arrays. Daarom vind ik het nodig om op een specifiek voorbehoud te wijzen.

In arrays, in tegenstelling tot gewone oude objecten, met delete laat afval achter in de vorm van null, het creëren van een "gat" in de array.

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

Zoals je kan zien, delete werkt niet altijd zoals je zou verwachten. De waarde wordt overschreven, maar het geheugen wordt niet opnieuw toegewezen. Het is te zeggen, array[4] is niet verplaatst naar array[3]. Dat staat in contrast met Array.prototype.unshift, dat een element invoegt in het begin van de array en alles opschuift (array[0] wordt array[1], enz.)

Eerlijk gezegd, afgezien van het instellen van null liever dan undefined- dat is legitiem raar - dit gedrag moet niet wees verrassend, sinds delete is een unaire operator, zoals typeof, dat is hardgekookt in de taal en mag niet om de taal schelen type van het voorwerp waarop het wordt gebruikt, terwijl Array is een subklasse van Object met methoden speciaal ontworpen voor werken met arrays. Er is dus geen goede reden voor deleteom een ​​speciaal geval in te kleuren voor het opnieuw verschuiven van de array, omdat dat alleen maar zou vertragen met onnodig werk. Achteraf bekeken waren mijn verwachtingen onrealistisch.

Natuurlijk deed Verras me. Omdat ik dit heb geschreven om mijn kruistocht te rechtvaardigen tegen "null garbage":

Het negeren van de gevaren en problemen die inherent zijn aan nullen de verspilling van de ruimte, dit kan problematisch zijn als de array nauwkeurig moet zijn.

Dat is een verschrikkelijke rechtvaardiging voor het wegwerken van de nullS-null is alleen gevaarlijk als het verkeerd wordt gebruikt en heeft niets te maken met "precisie". De echte reden dat je dat niet zou moeten doen delete van een array is omdat het achterlaten van rommel gevulde en rommelige datastructuren in de buurt slordig is en gevoelig voor fouten.

Wat volgt is een gekunsteld scenario dat behoorlijk langdradig wordt, dus je kunt doorgaan naar de sectie, De oplossing, als je wil. De enige reden dat ik deze sectie laat staan ​​is omdat ik denk dat sommige mensen het waarschijnlijk grappig vinden, en ik wil niet "die vent" zijn die een "grappig" antwoord plaatst en daarna alle "grappige" ervan later verwijdert .

... Het is stom, ik weet het.

Het gekunstelde en langdradige PDP-11-scenario

Stel bijvoorbeeld dat u een webapp maakt die JSON-serialisatie gebruikt om een ​​array op te slaan die wordt gebruikt voor 'tabs' in een tekenreeks (in dit geval localStorage). Laten we ook zeggen dat de code de numerieke indexen van de leden van de array gebruikt om ze te "titel" wanneer ze naar het scherm tekenen. Waarom doe je dit in plaats van alleen de "titel" op te slaan? Omdat... redenen.

Oké, laten we zeggen dat je op verzoek van dit geheugen geheugen probeert te besparen een gebruiker die een PDP-11 minicomputer draait vanaf de jaren 1960 met UNIX, en schreef zijn eigen Elinks-gebaseerde, JavaScript-compatibele, lijn-printer-vriendelijke browser omdat X11 is buiten de vraag.

Steeds dommer randscenario opzij, met behulp van delete op de array zal resulteren null de array vervuilen en later waarschijnlijk bugs in de app veroorzaken. En als u controleert nullzou het direct de getallen overslaan, resulterend in de tabs die worden weergegeven als [1] [2] [4] [5] ....

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

Ja, dat is absoluut niet wat je wilde.

Nu jij kon bewaar een tweede iterator, zoals j, om alleen te verhogen wanneer geldige waarden uit de array worden gelezen. Maar dat zou het probleem niet precies oplossen null probleem, en dat moet je nog steeds een plezier doen trol PDP-11 gebruiker. Helaas, zijn computer gewoon niet voldoende geheugen hebben om dat laatste gehele getal vast te houden (vraag niet hoe hij erin slaagt om een ​​array met variabele breedte te verwerken ...).

Dus stuurt hij je een e-mail in woede:

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

Over nu, je bent ten einde raad. Deze vent heeft non-stop over je app geklaagd en je wilt hem zeggen dat hij zijn mond moet houden en een betere computer moet gaan halen.

De oplossing: Array.prototype.splice

Gelukkig, arrays do hebben een gespecialiseerde methode voor het verwijderen van indices en het heralloceren van geheugen: Array.prototype.splice(). Je zou zoiets kunnen schrijven als dit:

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

En net als dat, heb je Mr. PDP-11 tevredengesteld. Hoera! (Ik zou hem nog steeds vertellen, hoewel ...)

Array.prototype.splice versus Array.prototype.slice

Ik vind het belangrijk om op het verschil tussen deze twee functies met dezelfde naam te wijzen, omdat ze allebei erg nuttig zijn.

Array.prototype.splice (start, n)

.splice() muteert de array en retourneert de verwijderde indexen. De array wordt uit de index gesneden, start, en n elementen zijn uitgesneden. Als n niet is opgegeven, wordt de hele reeks erna start is uitgeknipt (n = array.length - start).

let a = [5,4,3,2,1];
let chunk = a.splice(2,2);

// a     [5,4,3,2,1]
// start  0 1 2 - -
// n      - - 1 2 -

chunk; // [3,2]
a;     // [5,4,1]

Array.prototype.slice (start, einde)

.slice() is niet-destructief en retourneert een nieuwe array met de aangegeven indexen start naar end. Als end is niet gespecificeerd, het gedrag is hetzelfde als .splice() (end = array.length). Het gedrag is een beetje lastig, omdat om wat voor reden dan ook end indexen van 1 in plaats van 0. Ik weet niet waarom dit dit doet, maar zo is het. Ook als end <= start, het resultaat is een lege array.

let a = [5,4,3,2,1];
let chunks = [
    a.slice(2,0),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ];

// a             [5,4,3,2,1]
// start          0 1 2 - -
// end, for...    - - - - -
//   chunks[0]  0 - - - - -   
//   chunks[1]    1 2 - - -
//   chunks[2]    1 2 3 - -
//   chunks[3]    1 2 3 4 5

chunks; // [ [], [], [3], [3,2,1] ]
a;      // [5,4,3,2,1]

Dat is eigenlijk niet wat er gebeurt, maar het is gemakkelijker om op die manier te denken. Volgens MDN, hier is wat er daadwerkelijk gebeurt:

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

De index gespecificeerd door end wordt gewoon uitgesloten van de slice. De haakjesindices geven aan wat er wordt gesneden. Hoe het ook zij, het gedrag is niet intuïtief en het veroorzaakt ongetwijfeld een groot aantal fouten, dus het kan handig zijn om een ​​wrapper-functie te gebruiken om het gedrag van .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);
}

Merk op dat de wrapper-functie is ontworpen om zeer strikt te zijn over typen, en zal terugkeren null als er iets niet goed is. Dat omvat het plaatsen van een string zoals "3". Het wordt overgelaten aan de programmeur om ijverig te zijn over zijn types. Dit is om goede programmeerpraktijken aan te moedigen.

Update met betrekking tot is_array()

Dit is met betrekking tot dit (nu verwijderde) fragment:

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

Dus het blijkt dat er IS een ingebouwde manier is om te bepalen of een array echt een array is en dat is het ook Array.isArray(), geïntroduceerd in ECMAScript 5 (december 2009). Ik vond dit terwijl ik op zoek was om te zien of er een vraag was over het vertellen van arrays van objecten, om te zien of er een betere oplossing was dan de mijne, of om de mijne toe te voegen als die er niet waren. Dus, als u een versie van JavaScript gebruikt die ouder is dan ECMA 5, is er uw polyfill. Ik raad echter ten zeerste af om mijn is_array() functie, omdat het blijven ondersteunen van oude versies van JavaScript betekent doorgaan met het ondersteunen van de oude browsers die ze implementeren, wat betekent het aanmoedigen van het gebruik van onveilige software en het in gevaar brengen van gebruikers voor malware. Dus gebruik alsjeblieft Array.isArray(). Gebruik let en const. Gebruik de nieuwe functies die aan de taal worden toegevoegd. doe niet gebruik prefixen van leveranciers. Verwijder dat IE polypill van je website. Verwijder die XHTML <!CDATA[[... ook crap - we zijn in 2014 verhuisd naar HTML5. Hoe eerder iedereen de ondersteuning voor die oude / esoterische browsers intrekt, hoe sneller de browserleveranciers de webstandaard daadwerkelijk zullen volgen en de nieuwe technologie zullen omarmen, en des te sneller we kunnen doorgaan naar een veiliger web.


133
2017-09-18 00:56



Oude vraag, modern antwoord. Objectvernietiging gebruiken, een ECMAScript 6 functie, het is zo simpel als:

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

Of met het vragenvoorbeeld:

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

U kunt het in actie zien in de try-outeditor van Babel.


Bewerk:

Als u opnieuw wilt toewijzen aan dezelfde variabele, gebruikt u a let:

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

91
2017-11-08 18:02



Een ander alternatief is om de Underscore.js bibliotheek.

Let daar op _.pick() en _.omit() beide retourneren een kopie van het object en wijzigen het oorspronkelijke object niet rechtstreeks. Het toewijzen van het resultaat aan het originele object zou de slag moeten slaan (niet getoond).

Referentie: link  _.pick (object, * toetsen)

Retourneer een kopie van het object, gefilterd om alleen waarden te hebben voor de witte lijst (of reeks van geldige sleutels).

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

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

Referentie: link  _.omit (object, * toetsen)

Retourneer een kopie van het object, gefilterd om het te laten op de zwarte lijst geplaatste toetsen (of reeks toetsen).

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

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

Voor arrays, _.filter() en _.reject() kan op een vergelijkbare manier worden gebruikt.


65
2018-05-24 18:53



De term die u in uw vraagtitel hebt gebruikt Remove a property from a JavaScript object, kan op verschillende manieren worden geïnterpreteerd. De enige is om het te verwijderen voor het hele geheugen en de lijst met objecttoetsen of de andere is gewoon om het uit je object te verwijderen. Zoals in sommige andere antwoorden is vermeld, is de delete sleutelwoord is het belangrijkste deel. Laten we zeggen dat je je object hebt zoals:

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

Als je dat doet:

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

het resultaat zou zijn:

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

U kunt die specifieke sleutel verwijderen uit uw objecttoetsen, zoals:

delete myJSONObject["regex"];

Gebruik dan de toetsen van uw objecten Object.keys(myJSONObject) zou zijn:

["ircEvent", "method"]

Maar het gaat erom dat als je om het geheugen geeft en je wilt dat het hele object uit het geheugen wordt verwijderd, het wordt aanbevolen om het op null in te stellen voordat je de sleutel verwijdert:

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

Het andere belangrijke punt hier is om voorzichtig te zijn met uw andere verwijzingen naar hetzelfde object. Als u bijvoorbeeld een variabele maakt zoals:

var regex = myJSONObject["regex"];

Of voeg het toe als een nieuwe aanwijzer voor een ander object, zoals:

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

Dan zelfs als u het uit uw object verwijdert myJSONObject, dat specifieke object wordt niet uit het geheugen verwijderd, omdat het regex variabel en myOtherObject["regex"] hebben nog steeds hun waarden. Hoe kunnen we het object dan zeker uit het geheugen verwijderen?

Het antwoord zou zijn op verwijder alle verwijzingen die je in je code hebt, wees naar datzelfde object en ook niet gebruiken var om nieuwe verwijzingen naar dat object te maken. Dit laatste punt met betrekking tot var uitspraken, is een van de meest cruciale kwesties waar we meestal mee geconfronteerd worden, omdat we het gebruiken var instructies voorkomen dat het gemaakte object wordt verwijderd.

Wat betekent dat u in dat geval dat object niet kunt verwijderen omdat u het hebt gemaakt regex veranderlijk via a var verklaring, en als u dat doet:

delete regex; //False

Het resultaat zou zijn false, wat betekent dat uw verwijderingsinstructie niet is uitgevoerd zoals verwacht. Maar als u die variabele niet eerder had gemaakt en alleen had myOtherObject["regex"] als uw laatste bestaande referentie, had u dit gewoon kunnen doen door het te verwijderen zoals:

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

Met andere woorden, een JavaScript-object wordt gedood zodra er geen referentie meer in uw code naar dat object verwijst.


Bijwerken: Met dank aan @AgentME:

Een eigenschap instellen op nul voordat deze wordt verwijderd, wordt niet uitgevoerd   alles (tenzij het object is verzegeld door Object.seal en de   verwijderen mislukt. Dat is meestal niet het geval, tenzij u specifiek   proberen).

Voor meer informatie over Object.seal: Object.seal ()


33
2018-02-12 06:29



ECMAScript 2015 (of ES6) werd geleverd met ingebouwde reflecteren voorwerp. Het is mogelijk om objecteigenschappen te verwijderen door te bellen Reflect.deleteProperty () functie met doelobject en eigenschapssleutel als parameters:

Reflect.deleteProperty(myJSONObject, 'regex');

wat gelijk is aan:

delete myJSONObject['regex'];

Maar als de eigenschap van het object niet kan worden geconfigureerd, kan deze niet worden verwijderd, noch met de deleteProperty-functie, noch met de operator delete:

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

Object.freeze () maakt alle eigenschappen van het object niet configureerbaar (naast andere dingen). deleteProperty functie (evenals verwijder operator) komt terug false wanneer probeert om een ​​van zijn eigenschappen te verwijderen. Als de eigenschap configureerbaar is, wordt deze geretourneerd true, zelfs als eigendom niet bestaat.

Het verschil tussen delete en deleteProperty is bij gebruik van de strikte modus:

"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



Stel dat je een object hebt dat er zo uitziet:

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

Een objecteigenschap verwijderen

Als u de hele wilt gebruiken staff array, de juiste manier om dit te doen, zou zijn om dit te doen:

delete Hogwarts.staff;

Als alternatief kun je dit ook doen:

delete Hogwarts['staff'];

Evenzo zou het verwijderen van de hele studentenreeks gedaan worden door te callen delete Hogwarts.students; of delete Hogwarts['students'];.

Een arrayindex verwijderen

Als u nu een enkele medewerker of student wilt verwijderen, is de procedure een beetje anders, omdat beide eigenschappen zelf arrays zijn.

Als u de index van uw personeelslid kent, kunt u dit eenvoudig doen:

Hogwarts.staff.splice(3, 1);

Als u de index niet kent, moet u ook een index-zoekopdracht uitvoeren:

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

Notitie

Terwijl je technisch kunt gebruiken delete voor een array zou het gebruik ervan resulteren in incorrecte resultaten als u bijvoorbeeld belt Hogwarts.staff.length later. Met andere woorden, delete zou het element verwijderen, maar het zou de waarde van niet updaten length eigendom. Gebruik makend van delete zou ook uw indexering in de war sturen.

Dus, wanneer u waarden uit een object verwijdert, moet u altijd eerst overwegen of u te maken hebt met objecteigenschappen of dat u te maken hebt met arraywaarden en op basis daarvan de juiste strategie kiest.

Als je hiermee wilt experimenteren, kun je gebruiken deze Fiddle als een startpunt.


28
2018-02-21 18:09