Question Comment puis-je supprimer une propriété d'un objet JavaScript?


Dites que je crée un objet comme suit:

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

Quelle est la meilleure façon de retirer la propriété regex pour finir avec de nouvelles myObject comme suit?

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

4893
2017-10-16 10:57


origine


Réponses:


Comme ça:

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

Démo

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

console.log(myObject);

Pour toute personne intéressée à en savoir plus, Stack Overflow user kangax a écrit un blog incroyablement approfondi sur le delete déclaration sur leur blog, Comprendre la suppression. C'est fortement recommandé.


6817
2017-10-16 10:58



Opérateur delete est étonnamment lent!

Regarde le référence.

Supprimer est le seul moyen de supprimer les propriétés de l'objet sans les restes, mais cela fonctionne ~ 100 fois plus lent, par rapport à son "alternative", réglage object[key] = undefined.

Cette alternative n'est pas la bonne réponse à cette question! Mais, si vous l'utilisez avec précaution, vous pouvez accélérer considérablement certains algorithmes. Si vous utilisez delete dans les boucles et vous avez des problèmes avec la performance, lisez l'explication verbeuse.

Quand devrait-on utiliser delete et quand la valeur de undefined ?

Un objet peut être vu comme un ensemble de paires clé-valeur. Ce que j'appelle une «valeur» est une primitive ou une référence à un autre objet, connecté à cette «clé».

Utilisation delete, lorsque vous passez l'objet résultat au code sur lequel vous n'avez pas de contrôle (ou lorsque vous n'êtes pas sûr de votre équipe ou de vous-même).

Il supprime la clé de la hashmap.

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

Utiliser le paramètre pour undefined, quand vous vous souciez de la performance. Cela peut donner un sérieux coup de pouce à votre code.

le la clé reste à sa place dans la hashmap, seule la valeur est remplacée par undefined. Comprendre que for..in boucle continuera à parcourir cette clé.

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

En utilisant cette méthode, pas tous façons de déterminer l'existence de la propriété fonctionnera comme prévu.

Cependant, ce code:

object.field === undefined

se comportera de manière équivalente pour les deux méthodes.

Tests

Pour résumer, les différences sont toutes sur les moyens de déterminer l'existence de la propriété, et à propos de for..in boucle.

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

Méfiez-vous des fuites de mémoire!

En utilisant obj[prop] = undefined est plus rapide que de faire delete obj[prop], une autre considération importante est que obj[prop] = undefined peut ne pas toujours être approprié. delete obj[prop] supprime prop de obj et l'efface de la mémoire alors que obj[prop] = undefined définit simplement la valeur de prop à undefined qui laisse prop toujours en mémoire. Par conséquent, dans les cas où de nombreuses clés sont créées et supprimées, en utilisant obj[prop] = undefined peut forcer la réconciliation mémoire coûteuse (provoquant le gel de la page) et potentiellement une erreur de mémoire insuffisante. Examinez le code suivant.

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

Dans le code ci-dessus, faire simplement nodeRecords[i][lastTime] = undefined; causera une fuite de mémoire massive, car chaque image d'animation. À chaque trame, les 65536 éléments DOM occuperont 65536 emplacements supplémentaires, mais les 65536 emplacements précédents ne seront définis que de manière indéfinie, ce qui les laissera dans la mémoire. Allez-y, essayez d'exécuter le code ci-dessus dans la console et voyez par vous-même. Après avoir forcé une erreur de manque de mémoire, essayez de l'exécuter à nouveau, sauf avec la version suivante du code qui utilise le deleteopérateur à la place.

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

Comme vu dans l'extrait de code ci-dessus, il existe quelques rares cas d'utilisation appropriés pour delete opérateur. Cependant, ne vous inquiétez pas trop de ce problème. Cela ne deviendra un problème qu'avec les objets à longue durée de vie qui reçoivent de nouvelles clés constamment ajoutées. Dans tous les autres cas (ce qui est presque tous les cas dans la programmation du monde réel), il est plus approprié d'utiliser obj[prop] = undefined. Le but principal de cette section est simplement de porter ceci à votre attention afin que dans la rare possibilité que cela devienne un problème dans votre code, alors vous pouvez plus facilement comprendre le problème et ainsi ne pas perdre des heures à disséquer votre code pour localiser et comprendre ce problème.

Ne pas toujours régler à undefined

Un aspect de Javascript important est le polymorphisme. Le polymorphisme est lors de l'attribution des différents types de variable / slot-in-a-object comme vu ci-dessous.

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

Cependant, il existe deux principaux problèmes non résolus avec les tableaux polymorphiques:

  1. Ils sont lents et inefficaces de mémoire. Lors de l'accès à un index spécifique, au lieu de simplement obtenir le type global pour le tableau, le navigateur doit à la place obtenir le type sur une base par index, chaque index stockant les métadonnées supplémentaires de son type.
  2. Une fois polymorphe, toujours polymorphe. Lorsqu'un tableau est rendu polymorphe, le polymorphisme ne peut pas être annulé dans les navigateurs Webkit. Ainsi, même si vous restaurez un tableau polymorphe non polymorphe, il sera toujours stocké par le navigateur sous la forme d'un tableau polymorphe.

On peut assimiler le polymorphisme à une dépendance à la drogue. Au premier coup d'œil, il semble incroyablement lucratif: joli code duveteux. Ensuite, le codeur introduit leur tableau à la drogue du polymorphisme. Instantanément, le réseau polymorphe devient moins efficace, et il ne peut jamais devenir aussi efficace qu'il l'était auparavant puisqu'il est drogué. Pour corréler une telle situation à la vie réelle, quelqu'un sur la cocaïne pourrait même ne pas être capable d'utiliser une poignée de porte simple, encore moins être capable de calculer les chiffres de PI. De même, un tableau sur le médicament du polymorphisme ne peut jamais être aussi efficace qu'un tableau monomorphe.

Mais, comment une analogie de voyage de drogue se rapportent à la delete opération? La réponse hérite de la dernière ligne de code dans l'extrait ci-dessus. Ainsi, qu'il soit réexaminé, cette fois avec une torsion.

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

Observer. bar[1] = "" ne contraint pas le polymorphisme alors bar[1] = undefined Est-ce que. Par conséquent, il faut toujours, dans la mesure du possible, utiliser le type correspondant pour leurs objets afin de ne pas provoquer accidentellement de polymorphisme. Une telle personne peut utiliser la liste suivante comme référence générale pour les faire fonctionner. Cependant, veuillez ne pas utiliser explicitement les idées ci-dessous. Au lieu de cela, utilisez tout ce qui fonctionne bien pour votre code.

  • Lorsque vous utilisez un tableau / une variable typé à la primitive booléenne, utilisez soit false ou undefined comme la valeur vide. Tout en évitant le polymorphisme inutile est bon, réécrire tout votre code pour l'interdire explicitement entraînera probablement une baisse des performances. Utilisez un jugement commun!
  • Lorsque vous utilisez un tableau / une variable typé à la primitive numérique, utilisez 0 comme la valeur vide. Notez qu'en interne, il existe deux types de nombres: les entiers rapides (2147483647 à -2147483648 inclus) et les doubles à virgule flottante lente (autre chose que NaN et Infinity). Lorsqu'un entier est rétrogradé en double, il ne peut pas être promu en entier.
  • Lors de l'utilisation d'un tableau / variable typé à la primitive de chaîne, utilisez "" comme la valeur vide.
  • Lorsque vous utilisez un symbole, attendez, pourquoi utilisez-vous un symbole?!?! Les symboles sont mauvais juju pour la performance. Tout ce qui est programmé pour utiliser les symboles peut être reprogrammé pour ne pas utiliser de symboles, ce qui donne un code plus rapide sans symboles. Les symboles sont vraiment juste du méta-sucre super inefficace.
  • Lorsque vous utilisez autre chose, utilisez null.

Cependant, soyez conscient! Ne commencez pas tout à coup à le faire avec tout votre code préexistant, car il risquerait de casser un tel code préexistant et / ou d'introduire des bogues étranges. Au contraire, une telle pratique efficace doit être mise en œuvre dès le début, et lors de la conversion du code préexistant, il est recommandé de double, triple, quadruple vérifier toutes les lignes relatives à cette tentative de mise à niveau de l'ancien code. risqué car c'est gratifiant.


700
2018-02-12 17:48



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

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

Cela fonctionne dans Firefox et Internet Explorer, et je pense que cela fonctionne dans tous les autres.


192
2017-10-16 11:03



Mise à jour 2018-07-21: Pendant longtemps, je me suis senti embarrassé par cette réponse, alors je pense qu'il est temps que je la touche un peu. Juste un petit commentaire, une clarification, et un formatage pour aider à accélérer la lecture des parties inutilement longues et alambiquées de cette réponse.


LA VERSION COURTE

La réponse réelle à la question

Comme d'autres l'ont dit, vous pouvez utiliser delete.

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

Array équivalent

Ne pas delete à partir d'un tableau. Utilisation Array.prototype.splice au lieu.

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

LA VERSION LONGUE

JavaScript est un langage OOP, donc tout est un objet, y compris tableaux. Ainsi, je pense qu'il est nécessaire de souligner une mise en garde particulière.

Dans les tableaux, contrairement aux objets anciens, en utilisant delete laisse derrière les ordures sous la forme de null, créant un "trou" dans le tableau.

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

Comme vous pouvez le voir, delete ne fonctionne pas toujours comme on pourrait s'y attendre. La valeur est remplacée, mais la mémoire n'est pas réaffectée. C'est-à-dire, array[4] n'est pas relocalisé à array[3]. Ce qui est en contraste avec Array.prototype.unshift, qui insère un élément au début du tableau et décale tout (array[0] devient array[1], etc.)

Honnêtement, mis à part la mise à null plutôt que undefined--qui est légitimement étrange - ce comportement ne devrait pas être surprenant, puisque delete est un opérateur unaire, comme typeof, qui est dur dans la langue et n'est pas censé se soucier de la type de l'objet, il est utilisé, alors que Array est une sous-classe de Object avec des méthodes spécialement conçu pour travailler avec des tableaux. Donc, il n'y a pas de bonne raison pour deletefaire cuire un cas spécial pour re-déplacer le tableau, car cela ne ferait que ralentir le travail inutile. Rétrospectivement, mes attentes étaient irréalistes.

Bien sûr, il fait Surprends-moi. Parce que j'ai écrit ceci pour justifier ma croisade contre "null garbage":

Ignorant les dangers et les problèmes inhérents à nullet l'espace gaspillé, cela peut être problématique si le tableau doit être précis.

Ce qui est une justification terrible pour se débarrasser de la nulls--null est seulement dangereux s'il n'est pas utilisé correctement, et cela n'a rien à voir avec la "précision". La vraie raison pour laquelle vous ne devriez pas delete à partir d'un tableau est parce que laisser les structures de données remplies de déchets et malpropres autour est bâclée et sujettes aux bogues.

Ce qui suit est un scénario artificiel qui devient assez long, donc vous pouvez passer à la section, La solution, si tu veux. La seule raison pour laquelle je quitte cette section est parce que je pense que certaines personnes pensent que c'est drôle, et je ne veux pas être "ce mec" qui publie une réponse "drôle" et supprime ensuite tout "drôle" plus tard .

... C'est stupide, je sais.

Le scénario PDP-11 artificiel et long-vented

Par exemple, supposons que vous créez une application Web qui utilise la sérialisation JSON pour stocker un tableau utilisé pour les 'onglets' dans une chaîne (dans ce cas, localStorage). Disons aussi que le code utilise les indices numériques des membres du tableau pour les "titrer" quand ils dessinent à l'écran. Pourquoi faites-vous cela plutôt que de simplement stocker le "titre" aussi bien? Car... les raisons.

Ok, disons simplement que vous essayez d'économiser de la mémoire à la demande de cette un utilisateur qui exécute un mini-ordinateur PDP-11 à partir des années 1960 sous UNIX, et a écrit son propre navigateur basé sur Elinks, compatible JavaScript, ligne imprimante facile, car X11 est hors de question.

De plus en plus stupide scénario marginal-cas, en utilisant delete sur ledit tableau se traduira par null polluer le tableau, et probablement causer des bugs dans l'application plus tard. Et si vous vérifiez pour null, il serait directement sauter les numéros résultant des onglets étant rendu comme [1] [2] [4] [5] ....

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

Oui, ce n'est définitivement pas ce que tu voulais.

Maintenant, c'est à votre tour pourrait garder un second itérateur, comme j, à incrémenter uniquement lorsque des valeurs valides sont lues dans le tableau. Mais cela ne résoudrait pas null question, et vous devez toujours s'il vous plaît que troll PDP-11 utilisateur. Hélas, son ordinateur vient de ne pas avoir assez de mémoire pour contenir ce dernier entier (ne demandez pas comment il gère un tableau de largeur variable ...).

Alors, il t'envoie un mail en colère:

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

À propos maintenant, vous êtes à la fin de votre esprit. Ce gars s'est plaint sans arrêt de votre application, et vous voulez lui dire de se taire et d'aller chercher un meilleur ordinateur.

La solution: Array.prototype.splice

Heureusement, les tableaux faire avoir une méthode spécialisée pour supprimer des index et réallouer de la mémoire: Array.prototype.splice(). Vous pourriez écrire quelque chose comme ceci:

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

Et juste comme ça, vous avez plu à M. PDP-11. Hourra! (Je le lui dirais quand même ...)

Array.prototype.splice vs Array.prototype.slice

Je pense qu'il est important de souligner la différence entre ces deux fonctions nommées de la même manière, car elles sont toutes deux très utiles.

Array.prototype.splice (début, n)

.splice() mute le tableau et renvoie les indices supprimés. Le tableau est découpé à partir de l'index, start, et n les éléments sont découpés. Si n est non spécifié, le tableau entier après start est tranché (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 (début, fin)

.slice() est non destructif et renvoie un nouveau tableau contenant les indices indiqués start à end. Si end est laissé non spécifié, le comportement est le même que .splice() (end = array.length). Le comportement est un peu difficile car, pour une raison quelconque, end index de 1 au lieu de 0. Je ne sais pas pourquoi ça fait ça, mais c'est comme ça. Également si end <= start, le résultat est un tableau vide.

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]

Ce n'est pas ce qui se passe réellement, mais c'est plus facile de penser de cette façon. Selon MDN, voici ce qui se passe réellement:

// 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 spécifié par end est simplement exclu de la tranche. Les indices entre parenthèses indiquent ce qui est découpé en tranches. Quoi qu'il en soit, le comportement n'est pas intuitif et il est susceptible de provoquer sa juste part d'erreurs hors-un, donc vous pourriez trouver utile de faire une fonction wrapper pour émuler plus étroitement le comportement de .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);
}

Notez que la fonction wrapper est conçue pour être très stricte sur les types, et retournera null si quelque chose est éteint. Cela inclut de mettre dans une chaîne comme "3". Il appartient au programmeur d'être diligent au sujet de ses types. C'est pour encourager une bonne pratique de programmation.

Mise à jour concernant is_array()

C'est en rapport avec cet extrait (maintenant-enlevé):

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

Donc, en fait, il est en fait un moyen intégré de dire si un tableau est vraiment un tableau, et c'est Array.isArray(), introduit dans ECMAScript 5 (décembre 2009). J'ai trouvé cela en cherchant à voir s'il y avait une question demandant de dire des tableaux à partir d'objets, de voir s'il y avait une meilleure solution que la mienne, ou d'ajouter la mienne s'il n'y en avait pas. Donc, si vous utilisez une version de JavaScript antérieure à ECMA 5, il y a votre polyfill. Cependant, je recommande fortement de ne pas utiliser mon is_array() fonction, continuer à prendre en charge les anciennes versions de JavaScript signifie continuer à prendre en charge les anciens navigateurs qui les implémentent, ce qui signifie encourager l'utilisation de logiciels non sécurisés et mettre les utilisateurs à risque de logiciels malveillants. Alors s'il vous plaît, utilisez Array.isArray(). Utilisation let et const. Utilisez les nouvelles fonctionnalités ajoutées à la langue. Ne pas utiliser les préfixes du fournisseur. Effacer que IE polyfill merde de votre site Web. Supprimer ce XHTML <!CDATA[[... crap aussi, nous sommes passés à HTML5 en 2014. Plus tôt tout le monde retire son soutien à ces anciens navigateurs ésotériques, plus tôt les vendeurs de navigateurs suivront la norme Web et adopteront la nouvelle technologie, et plus tôt nous pourrons passer à un web plus sécurisé.


133
2017-09-18 00:56



Ancienne question, réponse moderne. En utilisant la déstructuration d'objet, un ECMAScript 6 fonctionnalité, c'est aussi simple que:

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

Ou avec l'échantillon de questions:

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

Vous pouvez le voir en action dans l'éditeur d'essai de Babel.


Modifier:

Pour réaffecter à la même variable, utilisez un let:

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

91
2017-11-08 18:02



Une autre alternative est d'utiliser le Underscore.js bibliothèque.

Notez que _.pick() et _.omit() les deux retournent une copie de l'objet et ne modifient pas directement l'objet original. Assigner le résultat à l'objet original devrait faire l'affaire (non montré).

Référence: lien  _.pick (objet, * touches)

Renvoie une copie de l'objet, filtrée pour avoir uniquement des valeurs pour le Clés en liste blanche (ou tableau de clés valides).

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

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

Référence: lien  _.omit (objet, * touches)

Renvoie une copie de l'objet, filtrée pour omettre le clés sur liste noire (ou tableau de clés).

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

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

Pour les tableaux, _.filter() et _.reject() peut être utilisé de la même manière.


65
2018-05-24 18:53



Le terme que vous avez utilisé dans le titre de votre question Remove a property from a JavaScript object, peut être interprété de différentes manières. L'un est de l'enlever pour l'ensemble de la mémoire et la liste des clés d'objet ou l'autre est juste pour le retirer de votre objet. Comme cela a été mentionné dans d'autres réponses, le delete mot-clé est la partie principale. Disons que vous avez votre objet comme:

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

Si tu fais:

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

le résultat serait:

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

Vous pouvez supprimer cette clé spécifique de vos clés d'objet comme:

delete myJSONObject["regex"];

Ensuite, vos objets clés en utilisant Object.keys(myJSONObject) serait:

["ircEvent", "method"]

Mais le fait est que si vous vous souciez de la mémoire et que vous voulez que l'objet soit retiré de la mémoire, il est recommandé de le mettre à zéro avant de supprimer la clé:

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

L'autre point important ici est de faire attention à vos autres références au même objet. Par exemple, si vous créez une variable comme:

var regex = myJSONObject["regex"];

Ou ajoutez-le comme un nouveau pointeur vers un autre objet comme:

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

Ensuite, même si vous le retirez de votre objet myJSONObject, cet objet spécifique ne sera pas supprimé de la mémoire, car le regex variable et myOtherObject["regex"] ont toujours leurs valeurs. Alors comment pourrions-nous retirer l'objet de la mémoire à coup sûr?

La réponse serait de supprimer toutes les références que vous avez dans votre code, pointé vers cet objet même et aussi Ne pas utiliser var instructions pour créer de nouvelles références à cet objet. Ce dernier point concernant var déclarations, est l'une des questions les plus cruciales auxquelles nous sommes habituellement confrontés, car var Les instructions empêcheraient la suppression de l'objet créé.

Ce qui signifie que dans ce cas, vous ne pourrez pas supprimer cet objet parce que vous avez créé regex variable via un var déclaration, et si vous faites:

delete regex; //False

Le résultat serait false, ce qui signifie que votre instruction delete n'a pas été exécutée comme prévu. Mais si vous n'aviez pas créé cette variable auparavant, et vous n'aviez myOtherObject["regex"] en tant que votre dernière référence existante, vous auriez pu le faire simplement en le supprimant comme ceci:

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

En d'autres termes, un objet JavaScript est tué dès qu'il n'y a plus de référence dans votre code pointé vers cet objet.


Mettre à jour: Merci à @AgentME:

Définir une propriété à null avant de la supprimer ne fonctionne pas   quoi que ce soit (sauf si l'objet a été scellé par Object.seal et   La suppression échoue. Ce n'est généralement pas le cas, sauf si vous spécifiquement   essayer).

Pour obtenir plus d'informations sur Object.seal: Object.seal ()


33
2018-02-12 06:29



ECMAScript 2015 (ou ES6) est livré avec built-in Réfléchir objet. Il est possible de supprimer la propriété de l'objet en appelant Reflect.deleteProperty () fonctionner avec l'objet cible et la clé de propriété en tant que paramètres:

Reflect.deleteProperty(myJSONObject, 'regex');

ce qui équivaut à:

delete myJSONObject['regex'];

Mais si la propriété de l'objet n'est pas configurable, elle ne peut être supprimée ni avec la fonction deleteProperty, ni avec l'opérateur delete:

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

Object.freeze () rend toutes les propriétés de l'objet non configurables (en plus d'autres choses). deleteProperty fonction (ainsi que supprimer l'opérateur) résultats false quand essaie de supprimer l'une de ses propriétés. Si la propriété est configurable, elle renvoie true, même si la propriété n'existe pas.

La différence entre delete et deleteProperty est en utilisant le mode strict:

"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



Supposons que vous ayez un objet qui ressemble à ceci:

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

Suppression d'une propriété d'objet

Si vous voulez utiliser l'ensemble staff tableau, la bonne façon de le faire, serait de faire ceci:

delete Hogwarts.staff;

Alternativement, vous pouvez aussi faire ceci:

delete Hogwarts['staff'];

De même, supprimer l'ensemble du tableau des étudiants serait fait en appelant delete Hogwarts.students; ou delete Hogwarts['students'];.

Suppression d'un index de tableau

Maintenant, si vous voulez supprimer un seul membre du personnel ou étudiant, la procédure est un peu différente, car les deux propriétés sont des tableaux eux-mêmes.

Si vous connaissez l'index de votre membre du personnel, vous pouvez simplement faire ceci:

Hogwarts.staff.splice(3, 1);

Si vous ne connaissez pas l'index, vous devrez également effectuer une recherche d'index:

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

Remarque

Alors que vous pouvez techniquement utiliser delete pour un tableau, l'utiliser entraînerait des résultats incorrects lors de l'appel par exemple Hogwarts.staff.length plus tard. En d'autres termes, delete supprimerait l'élément, mais ne mettrait pas à jour la valeur de length propriété. En utilisant delete serait également gâcher votre indexation.

Ainsi, lorsque vous supprimez des valeurs d'un objet, commencez toujours par déterminer si vous traitez des propriétés d'objet ou si vous traitez des valeurs de tableau, et choisissez la stratégie appropriée basée sur cela.

Si vous voulez expérimenter cela, vous pouvez utiliser ce violon comme point de départ.


28
2018-02-21 18:09