Comment supprimer une propriété d'un objet JavaScript ?

Disons que je crée un objet comme suit :

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

Quelle est la meilleure façon de supprimer la propriété regex pour obtenir le nouvel myObject suivant ?

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

Comme ça :

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

Démonstration

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

console.log(myObject);

Pour tous ceux qui souhaitent en savoir plus, l'utilisateur de Stack Overflow [kangax][1] a rédigé un billet incroyablement détaillé sur l'instruction delete sur son blog, [Understanding delete][2]. Nous vous le recommandons vivement.

[1] : https://stackoverflow.com/users/130652/kangax [2] : http://perfectionkills.com/understanding-delete/

Commentaires (17)
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.

Commentaires (0)

Mise à jour 2018-07-21: Pendant longtemps, je me suis senti gêné par cette réponse, alors je pense qu'il est temps que je la retouche 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

Équivalent d'un tableau

N'utilisez pas delete dans un tableau. Utilisez plutôt Array.prototype.splice.

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 *arrays*. Ainsi, je pense qu'il est nécessaire de souligner une mise en garde particulière. Dans les tableaux, contrairement aux objets ordinaires, l'utilisation de `delete` laisse derrière elle des déchets 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 écrasée, mais la mémoire n'est pas réallouée. En d'autres termes, array[4] n'est pas relocalisé dans array[3]. Contrairement à Array.prototype.unshift, qui insère un élément au début du tableau et décale tout vers le haut (array[0] devient array[1], etc.). Honnêtement, à part le fait de mettre à null plutôt qu'à undefined - ce qui est légitimement bizarre - ce comportement ne devrait pas être surprenant, puisque delete est un opérateur unaire, comme typeof, qui est ancré dans le langage et qui n'est pas censé se soucier du type d'objet sur lequel il est utilisé, alors que Array est une sous-classe de Object avec des méthodes spécifiquement conçues pour travailler avec des tableaux. Il n'y a donc aucune raison pour que delete ait un cas spécial pour déplacer le tableau, car cela ne ferait que ralentir les choses avec un travail inutile. Rétrospectivement, mes attentes étaient irréalistes. Bien sûr, cela m'a surpris. Parce que j'ai écrit ceci pour justifier ma croisade contre les "null garbage" :

En ignorant les dangers et les problèmes inhérents à null, et 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 des nulls - null n'est dangereux que s'il est utilisé incorrectement, et cela n'a rien à voir avec la "précision". La vraie raison pour laquelle vous ne devriez pas supprimer un tableau est que laisser des structures de données pleines de déchets et désordonnées est négligé et sujet à des bogues. Ce qui suit est un scénario inventé qui devient assez long, donc vous pouvez sauter à la section, La Solution, si vous voulez. La seule raison pour laquelle je laisse cette section est que je pense que certaines personnes la trouvent probablement amusante, et je ne veux pas être "ce type" qui poste une réponse "amusante" puis supprime tout ce qui est "amusant" par la suite. ...C'est stupide, je sais.

Le scénario inventé et interminable du PDP-11

Par exemple, disons que vous créez une application web qui utilise la sérialisation JSON pour stocker un tableau utilisé pour les 'tabs' dans une chaîne (dans ce cas, localStorage). Disons également que le code utilise les indices numériques des membres du tableau pour les "titrer" lors de l'affichage à l'écran. Pourquoi faire cela plutôt que de simplement stocker le "titre" également ? Parce que... raisons. Disons que vous essayez d'économiser de la mémoire à la demande de cet un seul utilisateur qui utilise un mini-ordinateur PDP-11 des années 1960 fonctionnant sous UNIX et qui a écrit son propre navigateur basé sur Elinks, compatible JavaScript et adapté à l'impression en ligne parce que X11 est hors de question. En dehors de ce scénario de plus en plus stupide, l'utilisation de delete sur ledit tableau aura pour conséquence de polluer le tableau avec null, ce qui causera probablement des bugs dans l'application par la suite. Et si vous vérifiez pour null, il sauterait directement les nombres résultant en un rendu des onglets comme [1] [2] [4] [5] .... if (array[index] == null) continuez ; else title = (index + 1).toString() ; /* 0 -> "1"

  • 1 -> "2"
  • 2 -> (rien)
  • 3 -> "4" / Oui, ce n'est certainement pas ce que vous vouliez. Maintenant, vous pourriez garder un second itérateur, comme j, pour ne l'incrémenter que lorsque des valeurs valides sont lues dans le tableau. Mais cela ne résoudrait pas exactement le problème du null, et vous devez toujours satisfaire cet troll utilisateur de PDP-11. Hélas, son ordinateur n'a tout simplement pas* assez de mémoire pour contenir ce dernier entier (ne demandez pas comment il arrive à gérer un tableau de largeur variable...). Alors, il vous envoie un e-mail de colère : Hey, votre webapp a cassé mon navigateur ! J'ai vérifié ma base de données localStorage après que votre code stupide ait provoqué une défaillance de mon navigateur, et voici ce que j'ai trouvé :

    "tabs :[ 'Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]" Après avoir effacé mes précieuses données, il s'est à nouveau planté, et j'ai fait un backtrace, et qu'est-ce que j'ai trouvé ? QU'EST-CE QUE JE TROUVE ? VOUS UTILISEZ TROP DE VARIABLES ! var i = index ; var j = 1 ; Grr, je suis en colère maintenant. -Troll Davidson Vous êtes à bout de nerfs. Ce type n'a pas arrêté de se plaindre 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 ont une méthode spécialisée pour effacer les indices et réallouer 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 fait plaisir à Mr. PDP-11. Hourra ! (Je le gronderais quand même...)

Array.prototype.splice vs Array.prototype.slice

Il me semble important de souligner la différence entre ces deux fonctions au nom similaire, car elles sont toutes deux très utiles.

Array.prototype.splice(start, n)

.splice() mute le tableau, et retourne les indices retirés. Le tableau est découpé à partir de l'indice start, et n éléments sont découpés. Si n n'est pas spécifié, le tableau entier après start est découpé (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, end)

.slice() est non-destructif et retourne un nouveau tableau contenant les indices indiqués de start à end. Si end n'est pas spécifié, le comportement est le même que celui de .splice() (end = array.length). Le comportement est un peu délicat car, pour une raison quelconque, end indexe à partir de 1 au lieu de 0. Je ne sais pas pourquoi il fait ça, mais c'est comme ça. Aussi, si `end

Commentaires (22)