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

6142

Supposons que je crée un objet comme suit:

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

Quelle est la meilleure façon de supprimer la propriété regexpour se retrouver avec nouveau myObjectcomme suit?

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
johnstok
la source
@EscapeNetscape C'est une question concernant le comportement, donc un benchmark dépeint la mauvaise image. Bien sûr, ce deleteserait l'option la plus lente car c'est une opération réelle plutôt que les deux autres qui ne sont que de simples affectations. Mais le point crucial de la question est que l' attribution de la propriété à nullou undefinedne supprime pas réellement la propriété de l'objet, mais définit la place que la propriété égale à une valeur constante particulière. (Les réponses ci-dessous expliquent pourquoi il s'agit d'une différence significative.)
Abion47

Réponses:

8309

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 quiconque souhaite en savoir plus à ce sujet, l'utilisateur de Stack Overflow kangax a écrit un article de blog incroyablement détaillé sur la deletedéclaration sur son blog, Understanding delete . C'est fortement recommandé.

nickf
la source
47
Vérifié, il fonctionne également avec "delete myJSONObject ['regex'];" Voir: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok
110
Un résultat de l'une des observations du lien "comprendre la suppression" ci-dessus est que, comme vous ne pouvez pas nécessairement supprimer une variable, mais uniquement des propriétés d'objet, vous ne pouvez donc pas supprimer une propriété d'objet "par référence" - var value = obj [ 'soutenir']; supprimer la valeur // ne fonctionne pas
Dexygen
27
Donc, il ne le supprime pas réellement? Cela devient indéfini, mais la clé existe toujours? Suis-je en train de manquer quelque chose?
Doug Molineux
152
@Pete non, il le supprime. Compte tenu: var x = {a : 'A', b : 'B'};Comparer: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */àx.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf
16
@ChristopherPfohl fonctionne pour moi. Comme je l'ai dit, c'est en fait assez approfondi, donc c'est un peu difficile à résumer. La réponse de base dans la réponse ci-dessus est suffisante pour presque tous les cas, le blog aborde quelques cas supplémentaires et les raisons pour lesquelles ces cas existent.
nickf
953

Les objets en JavaScript peuvent être considérés comme des correspondances entre les clés et les valeurs. L' deleteopérateur est utilisé pour supprimer ces clés, plus communément appelées propriétés d'objet, une à la fois.

var obj = {
  myProperty: 1    
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false

L' deleteopérateur ne libère pas directement la mémoire, et il diffère de simplement attribuer la valeur de nullou undefinedà une propriété, en ce que la propriété elle - même est supprimée de l'objet. Notez que si la valeur d'une propriété supprimée était un type de référence (un objet) et qu'une autre partie de votre programme contient toujours une référence à cet objet, cet objet ne sera bien sûr pas récupéré tant que toutes les références à celui-ci n'auront pas disparu.

delete ne fonctionnera que sur les propriétés dont le descripteur les marque comme configurables.

Dan
la source
43
une propriété est affectée à undefined est toujours une propriété d'un objet, donc il ne sera pas supprimé par GC, sauf si vous avez mal lu votre dernier paragraphe.
Lance
8
J'avais tort de toucher ici le thème du GC. Les deux méthodes ont le même résultat pour GC: elles suppriment la valeur liée à la clé. Si cette valeur était la dernière référence à un autre objet, cet objet serait nettoyé.
Dan
15
une propriété est affectée à undefined est toujours une propriété d'un objet, donc elle ne sera pas supprimée par GC Le GC ne gère rien sur les propriétés. Il collecte et supprime des valeurs. Tant que rien ne fait référence à une valeur (un objet, une chaîne, etc.), le GC la supprime de la mémoire.
meandre
8
BTW, c'est le double problème pour vérifier si une propriété existe sur un objet Javascript. L'utilisation de l' opérateur est fiable mais lente. Vérifiez si la propriété n'est pas indéfinie "n'est pas la bonne réponse" mais c'est un moyen plus rapide. check
rdllopes
8
Cette réponse est-elle toujours pertinente? jsperf est actuellement vers le bas, mais cette référence semble indiquer que la différence de vitesse est seulement 25%, ce qui est nulle part à proximité des « environ 100 fois plus lent » dans cette réponse.
Cerbrus
248

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.

carré rouge
la source
216

L' deleteopérateur est utilisé pour supprimer les propriétés des objets.

const obj = { foo: "bar" }
delete obj.foo
obj.hasOwnProperty("foo") // false

Notez que, pour les tableaux, ce n'est pas la même chose que de supprimer un élément . Pour supprimer un élément d'un tableau, utilisez Array#spliceou Array#pop. Par exemple:

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

Détails

deleteen JavaScript a une fonction différente de celle du mot-clé en C et C ++: il ne libère pas directement la mémoire. Au lieu de cela, son seul but est de supprimer les propriétés des objets.

Pour les tableaux, la suppression d'une propriété correspondant à un index crée un tableau clairsemé (c'est-à-dire un tableau contenant un "trou"). La plupart des navigateurs représentent ces indices de tableau manquants comme «vides».

var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]

Notez que deletene se déplace pas array[3]dans array[2].

Différentes fonctions intégrées en JavaScript gèrent différemment les tableaux clairsemés.

  • for...in sautera complètement l'index vide.

  • Une forboucle traditionnelle renverra undefinedla valeur à l'index.

  • Toute méthode utilisant Symbol.iteratorretournera undefinedla valeur à l'index.

  • forEach, mapEt reducesautera les index manquant.

Ainsi, l' deleteopérateur ne doit pas être utilisé dans le cas d'utilisation courant de suppression d'éléments d'un tableau. Les tableaux ont des méthodes dédiées pour supprimer des éléments et réallouer la mémoire: Array#splice()et Array#pop.

Array # splice (start [, deleteCount [, item1 [, item2 [, ...]]]])

Array#splicemute le tableau et renvoie tous les index supprimés. deleteCountles éléments sont supprimés de l'index startet item1, item2... itemNsont insérés dans le tableau à partir de l'index start. Si deleteCountest omis, les éléments de startIndex sont supprimés à la fin du tableau.

let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]

Il y a aussi un nom similaire, mais différente, fonction sur Array.prototype: Array#slice.

Array # slice ([début [, fin]])

Array#sliceest non destructif et renvoie un nouveau tableau contenant les indices indiqués de startà end. Si elle endn'est pas spécifiée, elle prend par défaut la fin du tableau. Si endest positif, il spécifie l' index non inclus de base zéro sur lequel s'arrêter. S'il endest négatif, il spécifie l'index sur lequel s'arrêter en comptant à partir de la fin du tableau (par exemple, -1 omettra l'index final). Si end <= start, le résultat est un tableau vide.

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

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

Array # pop

Array#popsupprime le dernier élément d'un tableau et renvoie cet élément. Cette opération modifie la longueur du tableau.

Braden Best
la source
12
Cette approche ne modifie pas l'objet d'origine qui pourrait encore être référencé ailleurs. Cela pourrait ou non être un problème selon la façon dont il est utilisé, mais c'est quelque chose à garder à l'esprit.
Tamas Czinege
19
@ B1KMusic Voici le moyen de supprimer un élément d'un tableau: splice
wulftone
3
@wulftone nope, qui divise le tableau et ne fait rien pour supprimer une valeur. Je pense vraiment que la meilleure façon de supprimer d'un tableau où des valeurs spécifiques doivent être supprimées est d'utiliser deleteet de créer une fonction Garbage Collection pour le nettoyer.
Braden Best
5
Je ne vois pas splicedans votre montage, mais removedevrait l'êtreArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-
1
Cet article est plein de taureau 1. Il ne répond pas à la question! 2. C'est un exemple de mauvaise utilisation du langage et de se plaindre que "ça ne marche pas!" 3. Ne blâmez pas l' opérateur de suppression JavaScript pour l'erreur idiosyncratique de Crockford consistant à mettre null pour un index de tableau vide. Il ne comprend pas le sens de null - il pense que c'est une erreur. L'erreur est la sienne et la seule - il n'y a pas de valeur nulle dans la valeur supprimée d'un index de tableau donné. Il n'y a pas de "trou" dans le tableau - c'est un index vide. Absolument légitime et attendu.
Bekim Bacaj
195

Vieille question, réponse moderne. À l'aide de la déstructuration d'objets, une fonctionnalité ECMAScript 6 , c'est aussi simple que:

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

Ou avec l'exemple 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 Babel.


Éditer:

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

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
Koen.
la source
6
Peut-être parce que le but est de supprimer une propriété d'un objet, pas d'en créer une nouvelle sans la propriété ... bien que votre solution soit ma préférée, car je préfère la voie immuable.
Vingt_centimes
8
La question indiquait "se retrouver avec un nouveau myObject".
Koen.
1
Ajout de soulignement pour enlever une propriété sera portée à votre projet :) Au lieu d'avoir disponible que regexvous pouvez également l' assigner à toute autre variable, par exemple _, ce qui est utilisé dans des langues comme Aller à jeter un résultat: const { regex: _, ...newObject } = myObject;.
Koen.
2
@PranayKumar J'espérais que cette syntaxe fonctionnerait; const { [key], ...newObject } = myObject;mais ce n'est pas le cas, donc je ne pense pas que ce soit possible avec la déstructuration.
Koen.
2
Avec freeze()les seal()objets 'd et ' d, vous ne pouvez pas simplement deleteune propriété. C'est donc une excellente alternative. Bien que dans la plupart des cas, il ne sera probablement pas logique de supprimer une propriété d'un objet gelé / scellé de toute façon, étant donné que le but est de donner certaines garanties sur vos structures de données, ce que ce modèle minerait. Pour les cas où vous devez duper de manière non destructive un objet mais sans certaines de ses propriétés, c'est parfait
Braden Best
119

Syntaxe de propagation (ES6)

À qui en a besoin ...

Pour terminer la réponse @Koen dans ce fil, au cas où vous voudriez supprimer une variable dynamique en utilisant la syntaxe étalée, vous pouvez le faire comme ceci:

const key = 'a';
        
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(foo);  // 1
console.log(rest); // { b: 2, c: 3 }

* foosera une nouvelle variable avec la valeur a(qui est 1).


RÉPONSE ÉTENDUE 😇
Il existe peu de façons courantes de supprimer une propriété d'un objet.
Chacun a ses avantages et ses inconvénients ( vérifiez cette comparaison de performances ):

Opérateur de suppression
Lisible et court, cependant, ce n'est peut-être pas le meilleur choix si vous travaillez sur un grand nombre d'objets car ses performances ne sont pas optimisées.

delete obj[key];


Réaffectation
Plus de 2 fois plus rapide quedelete, cependant, la propriété n'estpassupprimée et peut être itérée.

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


Opérateur de diffusion
CetES6opérateur nous permet de renvoyer un tout nouvel objet, à l'exclusion de toute propriété, sans muter l'objet existant. L'inconvénient est qu'il a les plus mauvaises performances de ce qui précède et qu'il n'est pas recommandé de l'utiliser lorsque vous devez supprimer de nombreuses propriétés à la fois.

{ [key]: val, ...rest } = obj;
Lior Elrom
la source
2
Je pense que la syntaxe de propagation / repos pour les littéraux d'objet n'a été incluse que dans ES2018 (ES9), pas ES6, même si plusieurs moteurs JS l'avaient déjà implémentée.
trincot
2
@trincot Il a été introduit pour la première fois en 2014 ( github.com/tc39/proposal-object-rest-spread ) et c'est une fonctionnalité ES6 (ECMAScript 2015 aka ECMAScript 6th Edition). Cependant, même si je me trompe, je ne pense pas que cela fasse une différence dans le contexte de la réponse.
Lior Elrom
2
Le lien se réfère à ES6 où la syntaxe étalée a été introduite pour les tableaux, mais il continue de proposer quelque chose de similaire pour les littéraux d'objets. Cette deuxième partie n'a été intégrée à ES9 que si je ne me trompe pas.
trincot
98

Une autre alternative consiste à utiliser la bibliothèque Underscore.js .

Notez que _.pick()et les _.omit()deux renvoient une copie de l'objet et ne modifient pas directement l'objet d'origine. L'affectation du résultat à l'objet d'origine devrait faire l'affaire (non représentée).

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

Renvoie une copie de l'objet, filtrée pour n'avoir que des valeurs pour les 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: link _.omit (objet, * touches)

Renvoie une copie de l'objet, filtrée pour omettre les 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 manière similaire.

Thaddeus Albers
la source
4
Gardez à l'esprit que si les clés de votre objet sont des nombres, vous devrez peut-être_.omit(collection, key.toString())
Jordan Arseno
Hmmmmm .... Le soulignement est ~ 100x plus lent que delete obj[prop]ce qui est ~ 100x plus lent que obj[prop] = undefined.
Jack Giffin
52

Le terme que vous avez utilisé dans le titre de votre question Remove a property from a JavaScript objectpeut être interprété de différentes manières. La première consiste à la supprimer pour toute la mémoire et la liste des clés d'objet ou l'autre consiste simplement à la supprimer de votre objet. Comme cela a été mentionné dans d'autres réponses, le deletemot-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"];

La clé de vos objets à utiliser Object.keys(myJSONObject)serait alors:

["ircEvent", "method"]

Mais le fait est que si vous vous souciez de la mémoire et que vous souhaitez que l'ensemble de l'objet soit supprimé de la mémoire, il est recommandé de le définir sur null 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 en tant que nouveau pointeur vers un autre objet comme:

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

Ensuite, même si vous le supprimez de votre objet myJSONObject, cet objet spécifique ne sera pas supprimé de la mémoire, car la regexvariable a myOtherObject["regex"]toujours ses valeurs. Alors, comment pourrions-nous supprimer 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 également de ne pas utiliser d' varinstructions pour créer de nouvelles références à cet objet . Ce dernier point concernant les varinstructions est l'un des problèmes les plus cruciaux auxquels nous sommes généralement confrontés, car l'utilisation d' varinstructions empêcherait la suppression de l'objet créé.

Ce qui signifie que dans ce cas, vous ne pourrez pas supprimer cet objet car vous avez créé la regexvariable via une varinstruction, et si vous le faites:

delete regex; //False

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

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 pointant vers cet objet.


Mise à jour: Merci à @AgentME:

Définir une propriété sur null avant de la supprimer n'accomplit rien (sauf si l'objet a été scellé par Object.seal et que la suppression échoue. Ce n'est généralement pas le cas, sauf si vous essayez spécifiquement).

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

Mehran Hatami
la source
Vous vous trompez - seuls les objets sont passés par référence en JavaScript, donc si myJSONObject.regexla valeur de est une chaîne et que vous l'assignez à un autre objet, l'autre objet a une copie de cette valeur.
Michał Perłakowski
Vous avez raison et voici une citation: "faites attention à vos autres références au même objet".
Mehran Hatami
43

ECMAScript 2015 (ou ES6) est livré avec un objet Reflect intégré . Il est possible de supprimer la propriété d'objet en appelant la fonction Reflect.deleteProperty () avec l'objet cible et la clé de propriété comme 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). deletePropertyLa fonction (ainsi que l' opérateur de suppression ) renvoie falselorsque tente de supprimer l'une de ses propriétés. Si la propriété est configurable, elle revient true, même si la propriété n'existe pas.

La différence entre deleteet deletePropertyest lors de l'utilisation du 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
madox2
la source
1
@Gothdo a plus d'avantages, surtout lorsque vous avez besoin de faire des choses fonctionnelles. Par exemple , vous pouvez assigner la fonction à la variable, passer comme argument ou de l' utilisation apply, call, bindfonctions ...
madox2
41

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 souhaitez utiliser l'intégralité du stafftableau, la manière appropriée de le faire serait de procéder comme suit:

delete Hogwarts.staff;

Alternativement, vous pouvez également faire ceci:

delete Hogwarts['staff'];

De même, la suppression de l'ensemble du tableau des étudiants se ferait en appelant delete Hogwarts.students;ou delete Hogwarts['students'];.

Suppression d'un index de tableau

Maintenant, si vous souhaitez 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 le faire:

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

Bien que vous puissiez techniquement l'utiliser deletepour un tableau, son utilisation entraînerait des résultats incorrects lors d'un appel par exemple Hogwarts.staff.lengthplus tard. En d'autres termes, deletesupprimerait l'élément, mais ne mettrait pas à jour la valeur de la lengthpropriété. L'utilisation deletegâcherait également votre indexation.

Ainsi, lorsque vous supprimez des valeurs d'un objet, considérez toujours d'abord si vous avez affaire à des propriétés d'objet ou si vous avez affaire à des valeurs de tableau, et choisissez la stratégie appropriée en fonction de cela.

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

John Slegers
la source
Je pense que vous devriez toujours utiliser splicesur un tableau au lieu de delete.
Joel Trauger du
@JoelTrauger: C'est ce que je dis ;-)
John Slegers
Oui. Mon commentaire est que cela deletene devrait même pas être une chose. C'est splicece que le PO recherchait.
Joel Trauger
1
@JoelTrauger: Comme j'ai essayé de l'expliquer, deletedevrait être utilisé pour les propriétés des objets et splicepour les éléments du tableau.
John Slegers
L'épissure est vraiment lente. Bien qu'il devrait être utilisé au lieu de deletesur des tableaux, il serait plus sage de ne pas créer du tout de code centré autour de lui.
Jack Giffin
39

Utilisation d'ES6:

(Opérateur Destructuration + Spread)

const myObject = {
    regex: "^http://.*",
    b: 2,
    c: 3
};
const { regex, ...noRegex } = myObject;
console.log(noRegex); // => { b: 2, c: 3 }
Srinivas
la source
Je ne pense pas que ce soit une fonctionnalité ES6, mais qui n'était incluse que dans ES9.
trincot
Donc en fait vous n'utilisez pas ES6, comme vous écrivez, mais ES9 ... ;-)
trincot
2
Il ne s'agit pas de supprimer une propriété d'un objet mais de créer un nouvel objet sans cette propriété.
Jordi Nebot
32

J'utilise personnellement Underscore.js ou Lodash pour la manipulation d'objets et de tableaux:

myObject = _.omit(myObject, 'regex');
emil
la source
31

L' opérateur de suppression est le meilleur moyen de le faire.

Un exemple en direct pour montrer:

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
Tarun Nagpal
la source
Il convient de noter que même si l'utilisation de l' deleteopérateur est saine en ce qui concerne la collecte des ordures , elle peut être étonnamment lente , en grande partie pour la même raison.
John Weisz
29

Pour cloner un objet sans propriété:

Par exemple:

let object = { a: 1, b: 2, c: 3 };   

Et nous devons supprimer «a».

1. avec clé prop explicite:

const { a, ...rest } = object;
object = rest;

2. avec clé prop variable:

const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;

3.Fonction de flèche froide 😎:

const removePropery = (propKey, { [propKey]: propValue, ...rest }) => rest;

object = removePropery('a', object);

4. Pour plusieurs propriétés

const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})

Usage

object = removeProperties(object, 'a', 'b') // result => { c: 3 }

Ou

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }
YairTawil
la source
1
Fonction flèche lisse!
JSilv
27

L' utilisation de la méthode de suppression est la meilleure façon de le faire, selon la description MDN, l'opérateur de suppression supprime une propriété d'un objet. Vous pouvez donc simplement écrire:

delete myObject.regex;
// OR
delete myObject['regex'];

L'opérateur de suppression supprime une propriété donnée d'un objet. En cas de suppression réussie, il renverra true, sinon false sera renvoyé. Cependant, il est important de considérer les scénarios suivants:

  • Si la propriété que vous essayez de supprimer n'existe pas, la suppression n'aura aucun effet et renverra true

  • Si une propriété du même nom existe sur la chaîne de prototype de l'objet, alors, après la suppression, l'objet utilisera la propriété de la chaîne de prototype (en d'autres termes, la suppression n'a d'effet que sur ses propres propriétés).

  • Aucune propriété déclarée avec var ne peut être supprimée de la portée globale ou de la portée d'une fonction.

  • En tant que tel, delete ne peut supprimer aucune fonction dans la portée globale (que cela fasse partie d'une définition de fonction ou d'une fonction (expression).

  • Les fonctions qui font partie d'un objet (en dehors de la
    portée globale) peuvent être supprimées avec delete.

  • Aucune propriété déclarée avec let ou const ne peut être supprimée de la portée dans laquelle elle a été définie. Les propriétés non configurables ne peuvent pas être supprimées. Cela inclut les propriétés des objets intégrés comme Math, Array, Object et les propriétés qui sont créées comme non configurables avec des méthodes comme Object.defineProperty ().

L'extrait de code suivant donne un autre exemple simple:

var Employee = {
      age: 28,
      name: 'Alireza',
      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

Pour plus d'informations et voir plus d'exemples, visitez le lien ci-dessous:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

Alireza
la source
22

Une autre solution, en utilisant Array#reduce.

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

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

Cependant, il mute l'objet d'origine. Si vous souhaitez créer un nouvel objet sans la clé spécifiée, affectez simplement la fonction de réduction à une nouvelle variable, par exemple:

(ES6)

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

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);

gentil utilisateur
la source
21

Ce message est très ancien et je le trouve très utile, j'ai donc décidé de partager la fonction non définie que j'ai écrite au cas où quelqu'un d'autre verrait ce message et se demander pourquoi ce n'est pas aussi simple que dans la fonction non définie PHP.

La raison de l'écriture de cette nouvelle unsetfonction est de conserver l'index de toutes les autres variables dans cette table de hachage. Regardez l'exemple suivant et voyez comment l'index de "test2" n'a pas changé après avoir supprimé une valeur de 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"}
talsibony
la source
20

Il y a beaucoup de bonnes réponses ici, mais je veux juste dire que lorsque vous utilisez delete pour supprimer une propriété en JavaScript, il est souvent sage de vérifier d'abord si cette propriété existe pour éviter les erreurs.

Par exemple

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}

En raison de la nature dynamique de JavaScript, il y a souvent des cas où vous ne savez tout simplement pas si la propriété existe ou non. Vérifier si obj existe avant le && s'assure également que vous ne lancez pas d'erreur en raison de l'appel de la fonction hasOwnProperty () sur un objet non défini.

Désolé si cela ne s'ajoute pas à votre cas d'utilisation spécifique, mais je pense que c'est une bonne conception à adapter lors de la gestion des objets et de leurs propriétés.

Willem
la source
2
supprimer foo.bar fonctionne même si la barre n'existe pas, donc votre test est un peu trop, à mon humble avis.
PhiLho
@PhiLho qui dépend de l'endroit où vous exécutez JavaScript. Dans Node.js, je crois que cela provoque le plantage de votre serveur.
Willem
2
delete foo.bar;lève une exception uniquement si foo est faux, ou si vous êtes en mode strict et foo est un objet avec une propriété de barre non configurable.
Macil
Je ne me souviens pas du problème exact que j'ai eu avec cela, mais je pense que le problème peut apparaître lorsque foo lui-même n'existe pas et que vous essayez de supprimer sa propriété.
Willem
Oui, vous devez tester si foo existe, sinon foo.bar lèvera une exception, mais vous n'avez pas besoin de vérifier l'existence de bar avant de le supprimer. C'est la partie «trop» de mon commentaire. :-)
PhiLho
16

En utilisant ramda # dissoc, vous obtiendrez un nouvel objet sans l'attribut regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

Vous pouvez également utiliser d'autres fonctions pour obtenir le même effet - omettre, choisir, ...

Amio.io
la source
15

Essayez la méthode suivante. Attribuez la Objectvaleur de la propriété à undefined. Ensuite, stringifyl'objet et parse.

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

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);

Mohammed Safeer
la source
1
AussiJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy
12

Si vous souhaitez supprimer une propriété profondément imbriquée dans l'objet, vous pouvez utiliser la fonction récursive suivante avec chemin d'accès à la propriété comme deuxième argument:

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

Exemple:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}
ayushgp
la source
Cette fonction fonctionne comme un charme, mais pourquoi avons-nous besoin d'un retour vrai et d'un retour faux? Ma version du code: codepen.io/anon/pen/rwbppY . Ma version échouera-t-elle dans tous les cas?
habituel à 0h07
@ witty2017, il n'échouera pas. L'endroit où j'ai utilisé la fonction devait également vérifier si la propriété existe déjà ou non. si la propriété n'existe pas, elle retournera false. S'il trouve la propriété et la supprime, il retournera vrai.
ayushgp
8

Vous pouvez simplement supprimer n'importe quelle propriété d'un objet en utilisant le deletemot - clé.

Par exemple:

var obj = {key1:"val1",key2:"val2",key3:"val3"}

Pour supprimer une propriété, par exemple key1, utilisez le deletemot - clé comme ceci:

delete obj.key1

Ou vous pouvez également utiliser une notation de type tableau:

delete obj[key1]

Réf: MDN .

Kalpesh Patel
la source
8

Object.assign () & Object.keys () & Array.map ()

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);

xgqfrms-gildata
la source
7

L'affirmation de Dan selon laquelle «supprimer» est très lente et la référence qu'il a publiée étaient douteuses. J'ai donc effectué le test moi-même dans Chrome 59. Il semble que "supprimer" soit environ 30 fois plus lent:

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

Notez que j'ai délibérément effectué plus d'une opération de suppression dans un cycle de boucle pour minimiser l'effet provoqué par les autres opérations.

Chong Lip Phang
la source
7

Envisagez de créer un nouvel objet sans la "regex"propriété, car l'objet d'origine pourrait toujours être référencé par d'autres parties de votre programme. Vous devez donc éviter de le manipuler.

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

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

console.log(newMyObject);

ideaboxer
la source
SyntaxError: Unexpected token '...'. Expected a property name.?
Krzysztof Przygoda
Essayez-le avec un navigateur moderne tel que Firefox, Chromium ou Safari. Et je m'attends à ce que cela fonctionne également avec Edge.
ideaboxer
Comme alternative, si vos clients vous obligent à prendre en charge des navigateurs obsolètes, vous pouvez envisager d'utiliser TypeScript qui transpile votre code en syntaxe héritée (+ vous offre l'avantage de la sécurité des types statiques).
ideaboxer
7

Suppression de propriété en JavaScript

Il existe de nombreuses options différentes présentées sur cette page, non pas parce que la plupart des options sont erronées - ou parce que les réponses sont des doublons - mais parce que la technique appropriée dépend de la situation dans laquelle vous vous trouvez et des objectifs des tâches que vous et / ou vous l'équipe essaie de réaliser. Pour répondre sans équivoque à votre question, il faut savoir:

  1. La version d'ECMAScript que vous ciblez
  2. La plage de types d'objets sur lesquels vous souhaitez supprimer des propriétés et le type de noms de propriété que vous devez pouvoir omettre (chaînes uniquement? Symboles )
  3. L'éthos / modèles de programmation que vous et votre équipe utilisez. Vous privilégiez les approches fonctionnelles et la mutation est verboten dans votre équipe, ou utilisez-vous des techniques orientées objet mutuelles du Far West?
  4. Cherchez-vous à réaliser cela en JavaScript pur ou êtes-vous disposé à utiliser une bibliothèque tierce?

Une fois que ces quatre questions ont été répondues, il existe essentiellement quatre catégories de «suppression de propriété» en JavaScript parmi lesquelles choisir afin d'atteindre vos objectifs. Elles sont:

Suppression de propriété d'objet mutatif, dangereuse

Cette catégorie est destinée à fonctionner sur des littéraux d'objet ou des instances d'objet lorsque vous souhaitez conserver / continuer à utiliser la référence d'origine et que vous n'utilisez pas de principes fonctionnels sans état dans votre code. Un exemple de syntaxe dans cette catégorie:

'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

Cette catégorie est la catégorie la plus ancienne, la plus simple et la plus largement prise en charge pour l'enlèvement de propriété. Il prend en charge les Symbolindex & array en plus des chaînes et fonctionne dans toutes les versions de JavaScript, à l'exception de la toute première version. Cependant, c'est une mutation qui viole certains principes de programmation et a des implications en termes de performances. Il peut également entraîner des exceptions non capturées lorsqu'il est utilisé sur des propriétés non configurables en mode strict .

Omission de propriété de chaîne basée sur le repos

Cette catégorie est destinée à fonctionner sur des instances d'objets ou de tableaux simples dans des versions ECMAScript plus récentes lorsqu'une approche non mutative est souhaitée et que vous n'avez pas besoin de prendre en compte les clés de symboles:

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 :(

Suppression de propriété d'objet mutatif, sûre

Cette catégorie est destinée à fonctionner sur des littéraux d'objet ou des instances d'objet lorsque vous souhaitez conserver / continuer à utiliser la référence d'origine tout en évitant que des exceptions ne soient levées sur des propriétés non configurables:

'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

De plus, bien que la mutation d'objets en place ne soit pas sans état, vous pouvez utiliser la nature fonctionnelle de Reflect.deletePropertypour effectuer une application partielle et d'autres techniques fonctionnelles qui ne sont pas possibles avec les deleteinstructions.

Omission de propriété de chaîne basée sur la syntaxe

Cette catégorie est destinée à fonctionner sur des instances d'objets ou de tableaux simples dans des versions ECMAScript plus récentes lorsqu'une approche non mutative est souhaitée et que vous n'avez pas besoin de prendre en compte les clés de symboles:

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 :(

Omission de propriété basée sur la bibliothèque

Cette catégorie permet généralement une plus grande flexibilité fonctionnelle, notamment la prise en compte des symboles et l'omission de plusieurs propriétés dans une seule instruction:

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"
james_womack
la source
var keyname = "KeyName"; supprimer mon objet [nom de clé];
Vikash Chauhan
7

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

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

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

Xiang
la source
@CoddWrench Désolé, je n'ai pas fait attention à voir cette réponse. Je réponds immédiatement après avoir vu delete myObject.regex;.
xiang
7

Vous pouvez utiliser la déstructuration ES6 avec l'opérateur de repos.

Les propriétés peuvent être supprimées en utilisant la déstructuration en combinaison avec l' opérateur de repos . Dans votre exemple, l'expression régulière est déstructurée (ignorée) et le reste des propriétés est renvoyé en tant que reste.

const noRegex = ({ regex, ...rest }) => rest;
const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

console.log(noRegex(myObjext)) //=> {  "ircEvent": "PRIVMSG","method": "newURI" }

Ou vous pouvez exclure dynamiquement des propriétés comme celle-ci,

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest

const removeRegex = removeProperty('regex') //=> {  "ircEvent": "PRIVMSG","method":"newURI" }
const removeMethod = removeProperty('method') //=> {  "ircEvent": "PRIVMSG", "regex":"^http://.*" }
Bhargav Patel
la source
7

Nous pouvons supprimer n'importe quelle propriété d'un objet javascript en utilisant ce qui suit:

  1. supprimer object.property
  2. supprimer l'objet ['propriété']

exemple:

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

console.log(myObject);

delete myObject.regex;
console.log('=================');
console.log(myObject);
delete myObject['method'];
console.log('=================');
console.log(myObject);

Ravi Ranjan
la source
6

Essaye ça

delete myObject['key'];
codemirror
la source