Comment puis-je ajouter une paire clé / valeur à un objet JavaScript?

1383

Voici mon objet littéral:

var obj = {key1: value1, key2: value2};

Comment puis-je ajouter un champ key3avec value3à l'objet?

James Skidmore
la source
2
Eh bien, tout le problème des tableaux associatifs dans JS est bizarre, car vous pouvez le faire ... dreaminginjavascript.wordpress.com/2008/06/27/…
Nosredna
@Nosredna - le fait est qu'il n'y a pas de tableaux associatifs en javascript. Dans cet article, il ajoute des propriétés d'objet à un objet tableau, mais celles-ci ne font pas vraiment partie du «tableau».
UpTheCreek
Existe-t-il un moyen de définir conditionnellement des paires clé: valeur dans un littéral objet avec les futures implémentations ES +?
Con Antonakos du

Réponses:

2253

Il existe deux façons d'ajouter de nouvelles propriétés à un objet:

var obj = {
    key1: value1,
    key2: value2
};

Utilisation de la notation par points:

obj.key3 = "value3";

Utilisation de la notation entre crochets:

obj["key3"] = "value3";

Le premier formulaire est utilisé lorsque vous connaissez le nom de la propriété. Le deuxième formulaire est utilisé lorsque le nom de la propriété est déterminé dynamiquement. Comme dans cet exemple:

var getProperty = function (propertyName) {
    return obj[propertyName];
};

getProperty("key1");
getProperty("key2");
getProperty("key3");

Un vrai tableau JavaScript peut être construit en utilisant soit:

La notation littérale du tableau:

var arr = [];

La notation constructeur Array:

var arr = new Array();
Ionuț G. Stan
la source
4
obj est un objet. La partie entre (et y compris) les accolades est le littéral de l'objet. obj n'est pas un objet littéral.
Nosredna
24
que faire si la clé est un nombre? obj.123 = 456 ne fonctionne pas. obj [123] = 456 fonctionne bien
axel freudiger
10
@axelfreudiger en effet, tout ce qui n'est pas syntaxiquement un identificateur de variable valide doit être utilisé avec une notation entre crochets.
Ionuț G. Stan
1
@KyleKhalafObject.keys({"b": 1, "c": 3, "a": 2}).sort().forEach(console.log);
Ionuț G. Stan
2
@JohnSmith la lengthpropriété n'est pas définie car ce n'est pas un tableau, c'est un objet / carte / dictionnaire.
Ionuț G. Stan
348

Réponse de l'année 2017: Object.assign()

Object.assign (dest, src1, src2, ...) fusionne les objets.

Il écrase les destpropriétés et les valeurs des objets source (aussi nombreux soient-ils), puis revient dest.

La Object.assign()méthode est utilisée pour copier les valeurs de toutes les propriétés propres énumérables d'un ou plusieurs objets source vers un objet cible. Il renverra l'objet cible.

Exemple en direct

var obj = {key1: "value1", key2: "value2"};
Object.assign(obj, {key3: "value3"});

document.body.innerHTML = JSON.stringify(obj);

Réponse de l'année 2018: opérateur de propagation d'objets {...}

obj = {...obj, ...pair};

De MDN :

Il copie ses propres propriétés énumérables d'un objet fourni vers un nouvel objet.

Le clonage superficiel (hors prototype) ou la fusion d'objets est désormais possible en utilisant une syntaxe plus courte que Object.assign().

Notez que Object.assign()déclenche des setters contrairement à la syntaxe de propagation.

Exemple en direct

Il fonctionne dans Chrome actuel et Firefox actuel. Ils disent que cela ne fonctionne pas dans Edge actuel.

var obj = {key1: "value1", key2: "value2"};
var pair = {key3: "value3"};
obj = {...obj, ...pair};

document.body.innerHTML = JSON.stringify(obj);

Réponse de l'année 2019

Opérateur d'affectation d'objets += :

obj += {key3: "value3"};

Oups ... je me suis emporté. La contrebande d'informations provenant du futur est illégale. Dûment obscurci!

7vujy0f0hy
la source
34
obj + = semble génial
Mehrdad Shokri
2
phpstorm recommande d'utiliser constet letau lieu de var, cela devrait-il être la manière 2018?
jim smith
@jimsmith: Je ne sais pas pourquoi vous dites cela ici. Voulez-vous mon avis? L'avantage d'un interprète est la possibilité de tout changer en direct dans la console. Je n'aime pas constparce que cela supprime cet avantage. Chaque fois que je l'ai utilisé, cela a entravé le développement.
7vujy0f0hy
nous sommes en 2019, cela signifie-t-il que l'opérateur d'affectation peut déjà être utilisé pour remplacer l'opérateur de propagation?
Mr-Programs
2
Un vrai programmeur appréciera le plaisir de soulager une profession toujours stressante. Votre Year 2019 answer ... Opps ...portion mérite un merci, vous avez fait ma journée . Meilleure réponse +1
ColinWa
89

J'ai adoré le LoDash / Underscore lors de l'écriture de projets plus importants.

L'ajout par obj['key']ou obj.keysont toutes des réponses JavaScript pures et solides. Cependant, les bibliothèques LoDash et Underscore fournissent de nombreuses fonctions supplémentaires pratiques lorsque vous travaillez avec des objets et des tableaux en général.

.push()est pour les tableaux , pas pour les objets .

Selon ce que vous recherchez, il existe deux fonctions spécifiques qui peuvent être agréables à utiliser et offrent des fonctionnalités similaires à la sensation de arr.push(). Pour plus d'informations, consultez les documents, ils contiennent de bons exemples.

_.merge (Lodash uniquement)

Le deuxième objet remplacera ou ajoutera à l'objet de base. undefinedles valeurs ne sont pas copiées.

var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
_.merge(obj, obj2);
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3"} 

_.extend / _.assign

Le deuxième objet remplacera ou ajoutera à l'objet de base. undefinedsera copié.

var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
_.extend(obj, obj2);
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3", key4: undefined}

_.defaults

Le deuxième objet contient des valeurs par défaut qui seront ajoutées à l'objet de base si elles n'existent pas. undefinedles valeurs seront copiées si la clé existe déjà.

var obj = {key3: "value3", key5: "value5"};
var obj2 = {key1: "value1", key2:"value2", key3: "valueDefault", key4: "valueDefault", key5: undefined};
_.defaults(obj, obj2);
console.log(obj);
// → {key3: "value3", key5: "value5", key1: "value1", key2: "value2", key4: "valueDefault"}

$ .extend

De plus, il peut être utile de mentionner jQuery.extend, il fonctionne de manière similaire à _.merge et peut être une meilleure option si vous utilisez déjà jQuery.

Le deuxième objet remplacera ou ajoutera à l'objet de base. undefinedles valeurs ne sont pas copiées.

var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
$.extend(obj, obj2); 
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3"}

Object.assign ()

Il peut être utile de mentionner le Object.assign ES6 / ES2015, il fonctionne de manière similaire à _.merge et peut être la meilleure option si vous utilisez déjà un polyfill ES6 / ES2015 comme Babel si vous souhaitez effectuer vous- même le polyfill .

Le deuxième objet remplacera ou ajoutera à l'objet de base. undefinedsera copié.

var obj = {key1: "value1", key2: "value2"};
var obj2 = {key2:"value4", key3: "value3", key4: undefined};
Object.assign(obj, obj2); 
console.log(obj);
// → {key1: "value1", key2: "value4", key3: "value3", key4: undefined}
Sir.Nathan Stassen
la source
Je crois que _.merge est maintenant _.extend (destination, autres)
AD
Ah, vous avez raison, _.extendc'est un alias plus universel puisque la bibliothèque de soulignement n'utilise toujours extendpas merge. Je mettrai à jour ma réponse.
Sir.Nathan Stassen
66

Vous pouvez utiliser l'une de ces options (à condition que key3 soit la clé réelle que vous souhaitez utiliser)

arr[ 'key3' ] = value3;

ou

arr.key3 = value3;

Si key3 est une variable, vous devez alors faire:

var key3 = 'a_key';
var value3 = 3;
arr[ key3 ] = value3;

Après cela, la requête arr.a_keyretournerait la valeur de value3, un littéral 3.

seth
la source
7
Ce n'est pas un tableau mais un objet. Les tableaux JS sont indexés uniquement par un entier. Essayez de faire arr.length et il retournera 0. Plus de lecture à ce sujet: less-broken.com/blog/2010/12/…
DevAntoine
Le lien @ DevAntoine n'est pas accessible. Si vous souhaitez obtenir la "longueur" de ce type de tableau, utilisez: Object.keys (your_array) .length Pour plus d'informations sur ce problème, voir: stackoverflow.com/questions/21356880/array-length-returns-0
Thế Anh Nguyễn
On pourrait également remplacer simplement la propriété length du tableau qu'ils créent. La définition de var myarray ["length"] = numArrayFields résout ce problème pour moi. En supposant que vous gardiez une trace du nombre de champs que vous ajoutez à votre tableau d'une manière ou d'une autre.
John Smith
30
arr.key3 = value3;

parce que votre arr n'est pas vraiment un tableau ... C'est un objet prototype. Le vrai tableau serait:

var arr = [{key1: value1}, {key2: value2}];

mais ce n'est toujours pas bien. Il devrait en fait être:

var arr = [{key: key1, value: value1}, {key: key2, value: value2}];
Robert Koritnik
la source
25
var employees = []; 
employees.push({id:100,name:'Yashwant',age:30});
employees.push({id:200,name:'Mahesh',age:35});
Vicky
la source
22
C'est pour les tableaux, pas pour les objets.
Roly
12

Ajouter simplement des propriétés:

Et nous voulons ajouter prop2 : 2à cet objet, ce sont les options les plus pratiques:

  1. Opérateur de points: object.prop2 = 2;
  2. crochets: object['prop2'] = 2;

Alors, lequel utilisons-nous alors?

L'opérateur point est une syntaxe plus propre et doit être utilisé par défaut (imo). Cependant, l'opérateur point n'est pas capable d'ajouter des clés dynamiques à un objet, ce qui peut être très utile dans certains cas. Voici un exemple:

const obj = {
  prop1: 1
}

const key = Math.random() > 0.5 ? 'key1' : 'key2';

obj[key] = 'this value has a dynamic key';

console.log(obj);

Fusion d'objets:

Lorsque nous voulons fusionner les propriétés de 2 objets, ce sont les options les plus pratiques:

  1. Object.assign(), prend un objet cible comme argument et un ou plusieurs objets source et les fusionnera. Par exemple:

const object1 = {
  a: 1,
  b: 2,
};

const object2 = Object.assign({
  c: 3,
  d: 4
}, object1);

console.log(object2);

  1. Opérateur de répartition d'objets ...

const obj = {
  prop1: 1,
  prop2: 2
}

const newObj = {
  ...obj,
  prop3: 3,
  prop4: 4
}

console.log(newObj);

Lequel utilisons-nous?

  • La syntaxe de propagation est moins verbeuse et doit être utilisée comme imo par défaut. N'oubliez pas de transpiler cette syntaxe en syntaxe prise en charge par tous les navigateurs car elle est relativement nouvelle.
  • Object.assign() est plus dynamique car nous avons accès à tous les objets qui sont passés comme arguments et pouvons les manipuler avant qu'ils ne soient affectés au nouvel objet.
Willem van der Veen
la source
1
En haut de votre message: ce ne sont pas des crochets mais des crochets.
Bram Vanroy
12

Performance

Aujourd'hui 2020.01.14 j'effectue des tests sur MacOs HighSierra 10.13.6 sur Chrome v78.0.0, Safari v13.0.4 et Firefox v71.0.0, pour les solutions choisies. Je divise les solutions en mutable (première lettre M) et immuable (première lettre I). Je propose également quelques solutions immuables (IB, IC, ID / IE) non encore publiées dans les réponses à cette question

Conclusions

  • les solutions mutables les plus rapides sont beaucoup plus rapides que les immuables les plus rapides (> 10x)
  • l'approche mutable classique comme obj.key3 = "abc"(MA, MB) est la plus rapide
  • pour les solutions immuables, les {...obj, key3:'abc'}et Object.assign(IA, IB) sont les plus rapides
  • étonnamment, il existe des solutions immuables plus rapidement que certaines solutions mutables pour le chrome (MC-IA) et safari (MD-IB)

entrez la description de l'image ici

Détails

Dans l'extrait ci-dessous, il y a une solution testée présumée, vous pouvez pré-tester sur votre machine ICI

entrez la description de l'image ici

Kamil Kiełczewski
la source
11

Je sais qu'il y a déjà une réponse acceptée pour cela, mais j'ai pensé documenter mon idée quelque part. S'il vous plaît [les gens] n'hésitez pas à percer cette idée, car je ne suis pas sûr que ce soit la meilleure solution ... mais je viens de mettre cela ensemble il y a quelques minutes:

Object.prototype.push = function( key, value ){
   this[ key ] = value;
   return this;
}

Vous l'utiliseriez de cette manière:

var obj = {key1: value1, key2: value2};
obj.push( "key3", "value3" );

Depuis, la fonction prototype revient, thisvous pouvez continuer à enchaîner .pushà la fin de votre objvariable:obj.push(...).push(...).push(...);

Une autre caractéristique est que vous pouvez passer un tableau ou un autre objet comme valeur dans les arguments de la fonction push. Voir mon violon pour un exemple de travail: http://jsfiddle.net/7tEme/

sadmicrowave
la source
peut-être que ce n'est pas une bonne solution, il semble que j'obtienne des erreurs dans jquery1.9: TypeError: 'undefined' is not a function (evaluating 'U[a].exec(s)')ce qui est bizarre car cela fonctionne dans jsfiddle même avec jquery1.9
sadmicrowave
3
Vous ne devez pas étendre Object.prototype; cela rompt la fonctionnalité "objet en tant que table de hachage" de JavaScript (et par la suite de nombreuses bibliothèques telles que l'API Google Maps JS). Voir la discussion: stackoverflow.com/questions/1827458/…
Justin R.
9

Vous pouvez créer une classe avec la réponse de @ Ionuț G. Stan

function obj(){
    obj=new Object();
    this.add=function(key,value){
        obj[""+key+""]=value;
    }
    this.obj=obj
}

Création d'un nouvel objet avec la dernière classe:

my_obj=new obj();
my_obj.add('key1', 'value1');
my_obj.add('key2', 'value2');
my_obj.add('key3','value3');

Impression de l'objet

console.log(my_obj.obj) // Return {key1: "value1", key2: "value2", key3: "value3"} 

Impression d'une clé

console.log(my_obj.obj["key3"]) //Return value3

Je suis novice en javascript, les commentaires sont les bienvenus. Travaille pour moi.

Eduen Sarceno
la source
7

Deux façons les plus utilisées déjà mentionnées dans la plupart des réponses

obj.key3 = "value3";

obj["key3"] = "value3";

Une autre façon de définir une propriété consiste à utiliser Object.defineProperty ()

Object.defineProperty(obj, 'key3', {
  value: "value3",       // undefined by default
  enumerable: true,      // false by default
  configurable: true,    // false by default
  writable: true         // false by default
});

Cette méthode est utile lorsque vous souhaitez avoir plus de contrôle lors de la définition d'une propriété. La propriété définie peut être définie comme énumérable, configurable et accessible en écriture par l'utilisateur.

Sanchay Kumar
la source
6

Votre exemple montre un objet, pas un tableau. Dans ce cas, la meilleure façon d'ajouter un champ à un objet est de simplement lui affecter, comme ceci:

arr.key3 = value3;
bdukes
la source
6

pris en charge par la plupart des navigateurs, et il vérifie si la clé d'objet disponible ou non que vous souhaitez ajouter, si elle est disponible, elle remplace la valeur de clé existante et si elle n'est pas disponible, elle ajoute la clé avec la valeur

Exemple 1

let my_object = {};

// now i want to add something in it  

my_object.red = "this is red color";

// { red : "this is red color"}

exemple 2

let my_object = { inside_object : { car : "maruti" }}

// now i want to add something inside object of my object 

my_object.inside_object.plane = "JetKing";

// { inside_object : { car : "maruti" , plane : "JetKing"} }

exemple 3

let my_object = { inside_object : { name : "abhishek" }}

// now i want to add something inside object with new keys birth , gender 

my_object.inside_object.birth = "8 Aug";
my_object.inside_object.gender = "Male";


    // { inside_object : 
//             { name : "abhishek",
//               birth : "8 Aug",
//               gender : "Male" 
//            }   
//       }
Abhishek Garg
la source
5

Dans le cas où vous avez plusieurs littéraux d'objets anonymes dans un objet et que vous souhaitez ajouter un autre objet contenant des paires clé / valeur, procédez comme suit:

Firebug 'the Object:

console.log(Comicbook);

Retour:

[Objet {name = "Spiderman", valeur = "11"}, Objet {name = "Marsipulami", valeur = "18"}, Objet {name = "Garfield", valeur = "2"}]

Code:

if (typeof Comicbook[3]=='undefined') {
    private_formArray[3] = new Object();
    private_formArray[3]["name"] = "Peanuts";
    private_formArray[3]["value"] = "12";
}

va ajouter Object {name="Peanuts", value="12"}à l'objet Comicbook

stevek
la source
bien et clairement expliqué une autre option qui est plus appropriée pour adresser des objets avec une propriété id ou name puis l'attribuer lors de l'ajout, bonne. spécialement quand il a ou pourrait avoir à l'avenir plus d'accessoires, la même méthode s'appliquera, il suffit de mettre un autre coma et il est prêt à changer de plan
Avia Afer
5

Soit obj['key3'] = value3ou obj.key3 = value3ajoutera la nouvelle paire auobj .

Cependant, je sais que jQuery n'a pas été mentionné, mais si vous l'utilisez, vous pouvez ajouter l'objet via $.extend(obj,{key3: 'value3'}). Par exemple:

var obj = {key1: 'value1', key2: 'value2'};
$('#ini').append(JSON.stringify(obj));

$.extend(obj,{key3: 'value3'});

$('#ext').append(JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="ini">Initial: </p>
<p id="ext">Extended: </p>

jQuery. étendre (cible [, objet1] [, objetN]) fusionne le contenu de deux ou plusieurs objets ensemble dans le premier objet.

Et il permet également des ajouts / modifications récursifs avec $.extend(true,object1,object2);:

Armfoot
la source
5

Une manière courte et élégante dans la prochaine spécification Javascript (étape 3 candidate) est:

obj = { ... obj, ... { key3 : value3 } }

Une discussion plus approfondie peut être trouvée dans Object spread vs Object.assign et sur le site du Dr. Axel Rauschmayers .

Il fonctionne déjà dans node.js depuis la version 8.6.0.

Vivaldi, Chrome, Opera et Firefox dans les versions à jour connaissent également cette fonctionnalité, mais Mirosoft ne le sait pas jusqu'à aujourd'hui, ni dans Internet Explorer ni dans Edge.

xyxyber
la source
5
var arrOfObj = [{name: 'eve'},{name:'john'},{name:'jane'}];
    var injectObj = {isActive:true, timestamp:new Date()};

    // function to inject key values in all object of json array

    function injectKeyValueInArray (array, keyValues){
        return new Promise((resolve, reject) => {
            if (!array.length)
                return resolve(array);

            array.forEach((object) => {
                for (let key in keyValues) {
                    object[key] = keyValues[key]
                }
            });
            resolve(array);
        })
    };

//call function to inject json key value in all array object
    injectKeyValueInArray(arrOfObj,injectObj).then((newArrOfObj)=>{
        console.log(newArrOfObj);
    });

Sortie comme ceci: -

[ { name: 'eve',
    isActive: true,
    timestamp: 2017-12-16T16:03:53.083Z },
  { name: 'john',
    isActive: true,
    timestamp: 2017-12-16T16:03:53.083Z },
  { name: 'jane',
    isActive: true,
    timestamp: 2017-12-16T16:03:53.083Z } ]
Sayed Tauseef Haider Naqvi
la source
4

Vous pouvez soit l'ajouter de cette façon:

arr['key3'] = value3;

ou de cette façon:

arr.key3 = value3;

Les réponses suggérant la saisie dans l'objet avec la variable key3ne fonctionneraient que si la valeur de key3était 'key3'.

wombleton
la source
4

Selon les accesseurs de propriétés définis dans ECMA-262 ( http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf , P67), il existe deux façons de faire pour ajouter des propriétés à un objet existe. Dans tous les cas, le moteur Javascript les traitera de la même manière.

La première façon consiste à utiliser la notation par points:

obj.key3 = value3;

Mais de cette façon, vous devez utiliser un IdentifierName après la notation par points.

La deuxième façon consiste à utiliser la notation entre crochets:

obj["key3"] = value3;

et une autre forme:

var key3 = "key3";
obj[key3] = value3;

De cette façon, vous pouvez utiliser une expression (inclure IdentifierName ) dans la notation entre crochets.

Chen Yang
la source
4

Nous pouvons également procéder de cette manière.

var myMap = new Map();
myMap.set(0, 'my value1');
myMap.set(1, 'my value2');
 for (var [key, value] of myMap) {
  console.log(key + ' = ' + value);
 }
Miraj Hamid
la source
1

Puisque c'est une question du passé mais le problème du présent. Suggère une autre solution: passez simplement la clé et les valeurs à la fonction et vous obtiendrez un objet de carte.

var map = {};
function addValueToMap(key, value) {
map[key] = map[key] || [];
map[key].push(value);
}
PPing
la source
2
Cela ne semble pas du tout lié à la question qui a été posée.
Quentin
0

Pour ajouter une paire valeur / clé à un objet, le for in fonctionne avec cet élément d'abord:

    var nwrow = {'newkey': 'value' };
    for(var column in row){
        nwrow[column] = row[column];
    }
    row = nwrow;
relipse
la source
0

Le meilleur moyen d'y parvenir est indiqué ci-dessous:

function getKey(key) {
  return `${key}`;
}

var obj = {key1: "value1", key2: "value2", [getKey('key3')]: "value3"};

//console.log(obj);
sgajera
la source
0

Vous pouvez créer un nouvel objet en utilisant la {[key]: value}syntaxe:

const foo = {
  a: 'key',
  b: 'value'
}

const bar = {
  [foo.a]: foo.b
}

console.log(bar); // {key: 'value'}
console.log(bar.key); // value

const baz = {
  ['key2']: 'value2'
}

console.log(baz); // {key2: 'value2'}
console.log(baz.key2); // value2

Avec la syntaxe précédente, vous pouvez maintenant utiliser la syntaxe étendue {...foo, ...bar}pour ajouter un nouvel objet sans muter votre ancienne valeur:

const foo = {a: 1, b: 2};

const bar = {...foo, ...{['c']: 3}};

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

Jonathan Stellwag
la source