Como posso adicionar um par de chave / valor a um objeto JavaScript?

1383

Aqui está o meu objeto literal:

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

Como posso adicionar campo key3com value3o objeto?

James Skidmore
fonte
2
Bem, toda a questão de matrizes associativas em JS é estranho, porque você pode fazer isso ... dreaminginjavascript.wordpress.com/2008/06/27/...
Nosredna
@Nosredna - o ponto é que não existem coisas como matrizes associativas em javascript. Nesse artigo, ele está adicionando propriedades de objeto a um objeto de matriz, mas essas não são realmente parte da 'matriz'.
UpTheCreek 30/08/2012
Existe uma maneira de definir condicionalmente pares de chave: valor em um literal de objeto com futuras implementações de ES +?
Con Antonakos

Respostas:

2253

Existem duas maneiras de adicionar novas propriedades a um objeto:

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

Usando notação de ponto:

obj.key3 = "value3";

Usando notação de colchete:

obj["key3"] = "value3";

O primeiro formulário é usado quando você sabe o nome da propriedade. O segundo formulário é usado quando o nome da propriedade é determinado dinamicamente. Como neste exemplo:

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

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

Uma matriz JavaScript real pode ser construída usando:

A notação literal de matriz:

var arr = [];

A notação do construtor Array:

var arr = new Array();
Ionuț G. Stan
fonte
4
obj é um objeto. A parte entre (e incluindo) as chaves é o objeto literal. obj não é um objeto literal.
Nosredna
24
e se a chave for um número? obj.123 = 456 não funciona. obj [123] = 456 funciona embora
Axel Freudiger
10
@axelfreudiger de fato, qualquer coisa que não seja sintaticamente um identificador de variável válido deve ser usada com a notação de colchete.
Ionuţ G. Stan
1
@KyleKhalafObject.keys({"b": 1, "c": 3, "a": 2}).sort().forEach(console.log);
Ionuț G. Stan
2
@JohnSmith a lengthpropriedade não está definida porque não é uma matriz, é um objeto / mapa / dicionário.
Ionuţ G. Stan
348

Resposta do ano de 2017: Object.assign()

Object.assign (dest, src1, src2, ...) mescla objetos.

Ele substitui as destpropriedades e os valores de (no entanto muitos) objetos de origem e retorna dest.

O Object.assign()método é usado para copiar os valores de todas as propriedades próprias enumeráveis ​​de um ou mais objetos de origem para um objeto de destino. Ele retornará o objeto de destino.

Exemplo ao vivo

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

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

Resposta do ano 2018: operador de propagação de objetos {...}

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

Do MDN :

Ele copia propriedades enumeráveis ​​próprias de um objeto fornecido para um novo objeto.

Agora é possível clonagem superficial (excluindo protótipo) ou mesclagem de objetos usando uma sintaxe mais curta que Object.assign().

Observe que Object.assign()aciona setters, enquanto a sintaxe de propagação não.

Exemplo ao vivo

Funciona no Chrome atual e no Firefox atual. Eles dizem que não funciona no Edge atual.

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

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

Resposta do ano de 2019

Operador de atribuição de objeto += :

obj += {key3: "value3"};

Opa ... Eu me empolguei. Contrabandear informações do futuro é ilegal. Devidamente obscurecido!

7vujy0f0hy
fonte
34
obj + = parece incrível
Mehrdad Shokri
2
O phpstorm recomenda o uso conste, em letvez de var, deve ser o caminho para 2018?
Jim Smith
@ jimsmith: Não sei por que você está dizendo isso aqui. Você quer minha opinião? A vantagem de um intérprete é a capacidade de alterar tudo ao vivo no console. Não gosto constporque remove essa vantagem. Toda vez que eu o usava, isso dificultava o desenvolvimento.
7vujy0f0hy
estamos em 2019, isso significa que o operador de atribuição já pode ser usado para substituir o operador de spread?
Mr-Programs
2
Um verdadeiro programador valorizará a diversão para proporcionar alívio a uma profissão sempre estressante. Sua Year 2019 answer ... Opps ...parte merece um agradecimento, você fez o meu dia . Melhor resposta +1
ColinWa 02/02/19
89

Apreciei o LoDash / Underscore ao escrever projetos maiores.

Adicionando obj['key']ou obj.keysão todas respostas JavaScript sólidas e puras. No entanto, as bibliotecas LoDash e Underscore fornecem muitas funções convenientes adicionais ao trabalhar com objetos e matrizes em geral.

.push()é para matrizes , não para objetos .

Dependendo do que você está procurando, há duas funções específicas que podem ser boas de utilizar e oferecem funcionalidade semelhante à sensação de arr.push(). Para mais informações, verifique os documentos, eles têm ótimos exemplos.

_.merge (apenas Lodash)

O segundo objeto substituirá ou adicionará ao objeto base. undefinedvalores não são copiados.

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

O segundo objeto substituirá ou adicionará ao objeto base. undefinedserá copiado.

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

O segundo objeto contém padrões que serão adicionados ao objeto base se eles não existirem. undefinedos valores serão copiados se a chave já existir.

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

Além disso, pode valer a pena mencionar o jQuery.extend, ele funciona de forma semelhante ao _.merge e pode ser uma opção melhor se você já estiver usando o jQuery.

O segundo objeto substituirá ou adicionará ao objeto base. undefinedvalores não são copiados.

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

Vale a pena mencionar o Object.assign do ES6 / ES2015, ele funciona de forma semelhante a _.merge e pode ser a melhor opção se você já estiver usando um polyfill do ES6 / ES2015 como Babel, se quiser se polyfill .

O segundo objeto substituirá ou adicionará ao objeto base. undefinedserá copiado.

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
fonte
Eu acredito que _.merge agora é _.extend (destino, outros)
AD
Ah, você está correto, _.extendé um alias mais universal, pois a biblioteca de sublinhado ainda extendnão está usando merge. Vou atualizar minha resposta.
Sir.Nathan Stassen
66

Você pode usar qualquer um destes (desde que key3 seja a chave acutal que você deseja usar)

arr[ 'key3' ] = value3;

ou

arr.key3 = value3;

Se key3 é uma variável, você deve fazer:

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

Depois disso, a solicitação arr.a_keyretornaria o valor de value3, um literal 3.

seth
fonte
7
Esta não é uma matriz, mas um objeto. Matrizes JS são indexadas apenas por número inteiro. Tente fazer arr.length e ele retornará 0. Mais leitura sobre isso: less-broken.com/blog/2010/12/…
DevAntoine
O link do @ DevAntoine não está acessível. Se você deseja obter o "comprimento" desse tipo de matriz, use: Object.keys (your_array) .length Mais informações sobre esse problema, consulte: stackoverflow.com/questions/21356880/array-length-returns-0
Thé Anh Nguyễn
Também é possível sobrescrever a propriedade length da matriz que eles estão criando. A definição de var myarray ["length"] = numArrayFields resolve esse problema para mim. Supondo que você esteja acompanhando o número de campos que está adicionando à sua matriz de alguma forma.
31518 John Smith
30
arr.key3 = value3;

porque sua arr não é realmente uma matriz ... É um objeto de protótipo. A matriz real seria:

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

mas ainda não está certo. Na verdade, deve ser:

var arr = [{key: key1, value: value1}, {key: key2, value: value2}];
Robert Koritnik
fonte
25
var employees = []; 
employees.push({id:100,name:'Yashwant',age:30});
employees.push({id:200,name:'Mahesh',age:35});
Vicky
fonte
22
Isto é para matrizes, não objetos.
Roly
12

Simplesmente adicionando propriedades:

E queremos adicionar prop2 : 2a esse objeto, estas são as opções mais convenientes:

  1. Operador de ponto: object.prop2 = 2;
  2. colchetes: object['prop2'] = 2;

Então, qual usamos então?

O operador de ponto é uma sintaxe mais limpa e deve ser usado como padrão (imo). No entanto, o operador de ponto não é capaz de adicionar chaves dinâmicas a um objeto, o que pode ser muito útil em alguns casos. Aqui está um exemplo:

const obj = {
  prop1: 1
}

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

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

console.log(obj);

Mesclando objetos:

Quando queremos mesclar as propriedades de 2 objetos, estas são as opções mais convenientes:

  1. Object.assign(), pega um objeto de destino como argumento e um ou mais objetos de origem e os mescla. Por exemplo:

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

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

console.log(object2);

  1. Operador de propagação de objeto ...

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

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

console.log(newObj);

Qual usamos?

  • A sintaxe de propagação é menos detalhada e deve ser usada como uma imo padrão. Não se esqueça de transpilar essa sintaxe para sintaxe, suportada por todos os navegadores, porque é relativamente nova.
  • Object.assign() é mais dinâmico porque temos acesso a todos os objetos que são passados ​​como argumentos e podemos manipulá-los antes de serem atribuídos ao novo objeto.
Willem van der Veen
fonte
1
Na parte superior da sua postagem: esses não são colchetes, mas colchetes.
Bram Vanroy 23/08/19
11

Sei que já existe uma resposta aceita para isso, mas pensei em documentar minha ideia em algum lugar. Por favor, [as pessoas] sintam-se à vontade para fazer furos nessa idéia, pois não tenho certeza se é a melhor solução ... mas acabei de montar isso alguns minutos atrás:

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

Você o utilizaria desta maneira:

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

Como a função prototype está retornando, thisvocê pode continuar encadeando .pushaté o final de sua objvariável:obj.push(...).push(...).push(...);

Outro recurso é que você pode passar uma matriz ou outro objeto como o valor nos argumentos da função push. Veja meu violino para um exemplo de trabalho: http://jsfiddle.net/7tEme/

sadmicrowave
fonte
talvez isso não é uma boa solução, eu pareço estar recebendo erros em jquery1.9: TypeError: 'undefined' is not a function (evaluating 'U[a].exec(s)')o que é estranho, porque ele funciona em jsFiddle mesmo com jquery1.9
sadmicrowave
3
Você não deve estender Object.prototype; isso quebra o recurso "objeto como hashtables" do JavaScript (e, posteriormente, muitas bibliotecas, como a API JS do Google Maps). Veja a discussão: stackoverflow.com/questions/1827458/…
Justin R.
11

atuação

Hoje 2020.01.14 realizo testes no MacOs HighSierra 10.13.6 no Chrome v78.0.0, Safari v13.0.4 e Firefox v71.0.0, para soluções escolhidas. Divido soluções para mutável (primeira letra M) e imutável (primeira letra I). Também forneço poucas soluções imutáveis ​​(IB, IC, ID / IE) ainda não publicadas em respostas a esta pergunta

Conclusões

  • as soluções mutáveis ​​mais rápidas são muito mais rápidas que as imutáveis ​​mais rápidas (> 10x)
  • A abordagem mutável clássica como obj.key3 = "abc"(MA, MB) é a mais rápida
  • para soluções imutáveis, {...obj, key3:'abc'}e Object.assign(IA, IB) são as mais rápidas
  • surpreendentemente, existem soluções imutáveis ​​mais rapidamente do que algumas soluções mutáveis ​​para chrome (MC-IA) e safari (MD-IB)

insira a descrição da imagem aqui

Detalhes

No snippet abaixo, há uma solução testada, você pode pré-testar na sua máquina AQUI

insira a descrição da imagem aqui

Kamil Kiełczewski
fonte
9

Você pode criar uma turma com a resposta de @ Ionuț G. Stan

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

Criando um novo objeto com a última classe:

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

Imprimindo o objeto

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

Imprimindo uma chave

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

Eu sou novato em javascript, comentários são bem-vindos. Funciona para mim.

Eduen Sarceno
fonte
7

Duas maneiras mais usadas já mencionadas na maioria das respostas

obj.key3 = "value3";

obj["key3"] = "value3";

Mais uma maneira de definir uma propriedade é usar 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
});

Este método é útil quando você deseja ter mais controle ao definir a propriedade. A propriedade definida pode ser definida como enumerável, configurável e gravável pelo usuário.

Sanchay Kumar
fonte
6

Seu exemplo mostra um objeto, não uma matriz. Nesse caso, a maneira preferida de adicionar um campo a um objeto é apenas atribuí-lo, assim:

arr.key3 = value3;
bdukes
fonte
6

apoiada pela maioria dos navegadores, e ele verifica se chave de objeto disponível ou não deseja adicionar, se disponível lo Overides valor de chave existente e não disponível lo adicionar chave com valor

Exemplo 1

let my_object = {};

// now i want to add something in it  

my_object.red = "this is red color";

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

exemplo 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"} }

exemplo 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
fonte
5

Caso você tenha vários literais de Objetos anônimos dentro de um Objeto e deseje adicionar outro Objeto contendo pares de chave / valor, faça o seguinte:

Firebug 'o objeto:

console.log(Comicbook);

retorna:

[Objeto {name = "Spiderman", valor = "11"}, Objeto {name = "Marsipulami", valor = "18"}, Objeto {name = "Garfield", valor = "2"}]

Código:

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

adicionará Object {name="Peanuts", value="12"}ao objeto Comicbook

stevek
fonte
explicou bem e claramente outra opção que é mais adequada para endereçar objetos com uma propriedade id ou name e depois atribuí-la ao adicionar, uma boa. especialmente quando se tem ou poderia ter, no futuro, mais adereços mesmo método será aplicado apenas colocar outra coma e está pronto para a mudança nos planos
Avia Afer
5

Quer obj['key3'] = value3ou obj.key3 = value3vai adicionar o novo par ao obj.

No entanto, eu sei que o jQuery não foi mencionado, mas se você o estiver usando, poderá adicionar o objeto $.extend(obj,{key3: 'value3'}). Por exemplo:

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. estender (destino [, objeto1] [, objetoN]) mescla o conteúdo de dois ou mais objetos juntos no primeiro objeto.

E também permite adições / modificações recursivas com $.extend(true,object1,object2);:

Armfoot
fonte
5

Uma maneira curta e elegante da próxima especificação Javascript (estágio candidato 3) é:

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

Uma discussão mais aprofundada pode ser encontrada em Propagação de objeto versus Object.assign e no site do Dr. Axel Rauschmayers .

Ele já funciona no node.js desde a liberação 8.6.0.

Vivaldi, Chrome, Opera e Firefox em versões atualizadas também conhecem esse recurso, mas a Mirosoft não conhece até hoje, nem no Internet Explorer nem no Edge.

xyxyber
fonte
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);
    });

Saída assim: -

[ { 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
fonte
4

Você pode adicioná-lo desta maneira:

arr['key3'] = value3;

ou desta maneira:

arr.key3 = value3;

As respostas sugerindo digitar o objeto com a variável key3só funcionariam se o valor de key3fosse 'key3'.

Wombleton
fonte
4

De acordo com os Acessadores de propriedades definidos no ECMA-262 ( http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf , P67), existem duas maneiras de você adicionar propriedades ao existe um objeto. Em todos esses sentidos, o mecanismo Javascript os tratará da mesma maneira.

A primeira maneira é usar a notação de ponto:

obj.key3 = value3;

Mas dessa maneira, você deve usar um IdentifierName após a notação de ponto.

A segunda maneira é usar a notação entre colchetes:

obj["key3"] = value3;

e outra forma:

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

Dessa forma, você pode usar uma Expressão (incluir IdentifierName ) na notação de colchete.

Chen Yang
fonte
4

Também podemos fazer isso dessa maneira.

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
fonte
1

Uma vez que é uma questão do passado, mas o problema do presente. Sugeriria mais uma solução: basta passar a chave e os valores para a função e você obterá um objeto de mapa.

var map = {};
function addValueToMap(key, value) {
map[key] = map[key] || [];
map[key].push(value);
}
PPing
fonte
2
Isso não parece estar relacionado à pergunta que foi feita.
Quentin
0

Para preceder um par de valores-chave em um objeto, o for in funciona com esse elemento, primeiro faça o seguinte:

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

A melhor maneira de conseguir o mesmo é declarada abaixo:

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

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

//console.log(obj);
sgajera
fonte
0

Você pode criar um novo objeto usando a {[key]: value}sintaxe:

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

Com a sintaxe anterior, agora você pode usar a sintaxe de dispersão {...foo, ...bar}para adicionar um novo objeto sem alterar seu valor antigo:

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
fonte