Eu preciso ser capaz de mesclar dois objetos JavaScript (muito simples) em tempo de execução. Por exemplo, eu gostaria de:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
Alguém tem um script para isso ou conhece uma maneira integrada de fazer isso? Não preciso de recursão e não preciso mesclar funções, apenas métodos em objetos simples.
javascript
javascript-objects
JC Grubbs
fonte
fonte
var obj2 = { animal: 'dog', food: 'bone' };
, a mesclagem seria{ food: 'bone', car: 'ford', animal: 'dog' }
. Se você estiver trabalhando com "dados aninhados" e desejar uma "mesclagem profunda", procure respostas que mencionem "mesclagem profunda" ou "recursão". Se você possui valoresarrays
, use a opção "arrayMerge" do github "TehShrike / deepmerge", conforme mencionado aqui .Respostas:
Método Padrão ECMAScript 2018
Você usaria a propagação de objeto :
merged
agora é a união deobj1
eobj2
. As propriedades emobj2
substituirão as que estão emobj1
.Aqui também está a documentação MDN para esta sintaxe. Se você estiver usando o babel, precisará do plug-in babel-plugin-transform-object-rest-spread para que ele funcione.
Método Padrão ECMAScript 2015 (ES6)
(consulte Referência JavaScript MDN )
Método para ES5 e anteriores
Note que isso irá simplesmente adicionar todos os atributos de
obj2
queobj1
o que pode não ser o que você quer se você ainda quiser usar o não modificadaobj1
.Se você estiver usando uma estrutura que excreta todos os seus protótipos, será necessário ficar mais sofisticado com verificações como
hasOwnProperty
, mas esse código funcionará em 99% dos casos.Exemplo de função:
fonte
var merged = {...obj1, ...obj2}
.{...obj1, ...{animal: 'dog'}}
O jQuery também possui um utilitário para isso: http://api.jquery.com/jQuery.extend/ .
Retirado da documentação do jQuery:
O código acima irá alterar o objeto existente nomeado
settings
.Se você deseja criar um novo objeto sem modificar nenhum argumento, use este:
fonte
jQuery.extend(true,settings,override)
, o que é importante se uma propriedade nas configurações retiver um objeto e substituir apenas uma parte desse objeto. Em vez de remover as propriedades incomparáveis, a configuração profunda será atualizada apenas onde existir. O padrão é falso.O Harmony ECMAScript 2015 (ES6) especifica
Object.assign
quem fará isso.O suporte atual ao navegador está melhorando , mas se você estiver desenvolvendo para navegadores sem suporte, poderá usar um polyfill .
fonte
Object.assign
tem uma cobertura bastante decente: kangax.github.io/compat-table/es6/...Object.assign({}, obj1, obj2)
Pesquisei no código o código para mesclar propriedades do objeto e acabei aqui. No entanto, como não havia nenhum código para mesclagem recursiva, eu mesmo o escrevi. (Talvez o jQuery extend seja BTW recursivo?) De qualquer forma, espero que alguém ache isso útil também.
(Agora o código não usa
Object.prototype
:)Código
Um exemplo
Produz o objeto o3 como
fonte
Observe que
underscore.js
's-extend
method faz isso em uma linha:fonte
_({}).extend(obj1, obj2);
_.defaults(object, *defaults)
"Preencha as propriedades nulas e indefinidas no objeto com valores dos objetos padrão e retorne o objeto".var mergedObj = _.extend({}, obj1, obj2)
.Semelhante ao jQuery extend (), você tem a mesma função no AngularJS :
fonte
Preciso mesclar objetos hoje, e essa pergunta (e respostas) me ajudou muito. Tentei algumas das respostas, mas nenhuma delas atendia às minhas necessidades, então combinei algumas, adicionei algo e criei uma nova função de mesclagem. Aqui está:
Alguns exemplos de uso:
fonte
merge({}, t1, { key1: 1 })
?Você pode usar propriedades de propagação de objeto - atualmente uma proposta de estágio 3 do ECMAScript.
fonte
As soluções fornecidas devem ser modificadas para verificar
source.hasOwnProperty(property)
osfor..in
loops antes da atribuição - caso contrário, você acaba copiando as propriedades de toda a cadeia de protótipos, o que raramente é desejado ...fonte
Mesclar propriedades de N objetos em uma linha de código
Um
Object.assign
método faz parte do padrão ECMAScript 2015 (ES6) e faz exatamente o que você precisa. (IE
não suportado)Consulte Mais informação...
O polyfill para suportar navegadores mais antigos:
fonte
Objects.assign
retorna um objeto mesclado que as outras respostas não. Esse é um estilo de programação mais funcional.Os dois seguintes são provavelmente um bom ponto de partida. O lodash também possui uma função de personalização para essas necessidades especiais!
_.extend
( http://underscorejs.org/#extend )_.merge
( https://lodash.com/docs#merge )fonte
A propósito, tudo o que você está fazendo é sobrescrever propriedades, não mesclar ...
É assim que a área de objetos JavaScript realmente é mesclada: somente as chaves no
to
objeto que não são objetos serão sobrescritasfrom
. Todo o resto será realmente mesclado . Obviamente, você pode alterar esse comportamento para não substituir nada que exista apenas seto[n] is undefined
, etc ...:Uso:
fonte
Aqui está minha facada que
É curto :)
Exemplo:
fonte
{}
como o primeiro parâmetro ou se a função modificar o objeto original. Portanto, se você mudardst = {}
paradst = arguments[0]
ele vai mudar o primeiro objeto que você passa para o objeto mescladotoString.call(src) == '[object Object]'
para verificar se há um objeto ou não.typeof src
é muito melhor. Além disso, transforma Arrays em objeto (pelo menos, eu tenho esse comportamento no Chrome mais recente).Object.assign ()
ECMAScript 2015 (ES6)
Esta é uma nova tecnologia, parte do padrão ECMAScript 2015 (ES6). A especificação dessa tecnologia foi finalizada, mas verifique a tabela de compatibilidade quanto ao status de uso e implementação em vários navegadores.
O método Object.assign () é usado para copiar os valores de todas as propriedades enumeráveis de um ou mais objetos de origem para um objeto de destino. Ele retornará o objeto de destino.
fonte
Para objetos não muito complicados, você pode usar JSON :
Lembre-se de que neste exemplo "} {" não deve ocorrer dentro de uma string!
fonte
var so1 = JSON.stringify(obj1); var so2 = JSON.stringify(obj1); objMerge = so1.substr(0, so1.length-1)+","+so2.substr(1); console.info(objMerge);
function merge(obj1, obj2) { return JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)) .replace(/\}\{/g, ',').replace(/,\}/g, '}').replace(/\{,/g, '{')); }
objMerge = JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)).replace(/\}\{/, ", "));
Há uma biblioteca chamada
deepmerge
no GitHub : Isso parece estar ficando alguma tração. É autônomo, disponível através dos gerenciadores de pacotes npm e bower.Eu estaria inclinado a usar ou melhorar isso em vez de copiar e colar o código das respostas.
fonte
A melhor maneira de fazer isso é adicionar uma propriedade adequada que não seja enumerável usando Object.defineProperty.
Dessa forma, você ainda poderá iterar nas propriedades dos objetos sem ter o "estender" recém-criado que você obteria se criasse a propriedade com Object.prototype.extend.
Espero que isso ajude:
Depois de ter esse trabalho, você pode fazer:
Acabei de escrever um post sobre o assunto aqui: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
fonte
Você pode simplesmente usar o jQuery
extend
Agora
obj1
contém todos os valores deobj1
eobj2
fonte
jQuery.extend( target [, object1 ] [, objectN ] )
O protótipo possui:
obj1.extend(obj2)
fará o que você quiser.fonte
Object.prototype
e nãoObject
... Boa ideia ou não, é isso que aprototype.js
estrutura faz e, portanto, se você a estiver usando ou outra estrutura que depende dela,Object.prototype
ela já será estendidaextend
.Object.prototype
?Object.extend
não interfere com seus objetos, apenas anexa uma função a umObject
objeto. Eobj1.extend(obj2)
não é o caminho correto para a função de fogo, usoObject.extend(obj1, obj2)
insted** A fusão de objetos é simples de usar
Object.assign
ou o...
operador spread **Os objetos são mesclados da direita para a esquerda, isso significa que os objetos que possuem propriedades idênticas aos objetos à direita serão substituídos.
Neste exemplo,
obj2.car
substituiobj1.car
fonte
Apenas se alguém estiver usando a Google Closure Library :
Função auxiliar semelhante existe para a matriz :
fonte
Estendi o método de David Coallier:
Se a substituição for falsa, nenhuma propriedade será substituída, mas novas propriedades serão adicionadas.
Uso: obj.merge (mescla ... [, substitui]);
Aqui está o meu código:
Exemplos e casos de teste:
Meu método equals pode ser encontrado aqui: Comparação de objetos em JavaScript
fonte
No MooTools , há Object.merge () :
fonte
No Ext JS 4, isso pode ser feito da seguinte maneira:
Veja mesclagem (objeto): Objeto .
fonte
Uau .. este é o primeiro post StackOverflow que eu já vi com várias páginas. Desculpas por adicionar outra "resposta"
Este método é para o ES5 e versões anteriores - existem muitas outras respostas para o ES6.
Não vi nenhum objeto "profundo" mesclado utilizando a
arguments
propriedade Aqui está a minha resposta - compacta e recursiva , permitindo que argumentos de objetos ilimitados sejam passados:A parte comentada é opcional. Ela simplesmente ignorará os argumentos passados que não são objetos (evitando erros).
Exemplo:
fonte
Usando jQuery.extend () - Link
Usando _.merge () - Link
Usando _.extend () - Link
Usando Object.assign () ECMAScript 2015 (ES6) - Link
Saída de todos
fonte
Com base nas respostas de Markus e vsync , esta é uma versão expandida. A função aceita qualquer número de argumentos. Ele pode ser usado para definir propriedades nos nós DOM e fazer cópias profundas dos valores. No entanto, o primeiro argumento é dado por referência.
Para detectar um nó DOM, a função isDOMNode () é usada (consulte a pergunta sobre estouro de pilha JavaScript isDOM - Como você verifica se um objeto JavaScript é um objeto DOM? )
Foi testado no Opera 11, Firefox 6, Internet Explorer 8 e Google Chrome 16.
Código
Alguns exemplos
Definir innerHTML e estilo de um elemento HTML
Mesclar matrizes e objetos. Observe que undefined pode ser usado para preservar valores na matriz / objeto à esquerda.
Qualquer argumento que não seja um objeto JavaScript (incluindo nulo) será ignorado. Exceto pelo primeiro argumento, também os nós DOM são descartados. Cuidado, isto é, seqüências de caracteres, criadas como novas String (), são de fato objetos.
Se você deseja mesclar dois objetos em um novo (sem afetar nenhum dos dois), forneça {} como primeiro argumento
Editar (por ReaperSoon):
Para mesclar também matrizes
fonte
fonte
Você deve usar os padrões do lodash
fonte
Com o Underscore.js , para mesclar uma matriz de objetos, faça:
Isso resulta em:
fonte