Necesito poder fusionar dos objetos JavaScript (muy simples) en tiempo de ejecución. Por ejemplo, me gustaría:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
¿Alguien tiene un script para esto o sabe de una manera integrada de hacer esto? No necesito recursividad, y no necesito fusionar funciones, solo métodos en objetos planos.
javascript
javascript-objects
JC Grubbs
fuente
fuente
var obj2 = { animal: 'dog', food: 'bone' };
, la fusión sería{ food: 'bone', car: 'ford', animal: 'dog' }
. Si está trabajando con "datos anidados" y desea una "fusión profunda", busque respuestas que mencionen "fusión profunda" o "recursión". Si tiene valores que sonarrays
, entonces use la opción "arrayMerge" de github "TehShrike / deepmerge", como se menciona aquí .Respuestas:
Método estándar de ECMAScript 2018
Se podría utilizar objeto propagación :
merged
ahora es la unión deobj1
yobj2
. Las propiedades enobj2
sobrescribirán aquellas enobj1
.Aquí también está la documentación de MDN para esta sintaxis. Si está utilizando babel, necesitará el complemento babel-plugin-transform-object-rest-spread para que funcione.
Método estándar de ECMAScript 2015 (ES6)
(vea la referencia de JavaScript de MDN )
Método para ES5 y anteriores
Tenga en cuenta que esto sólo tiene que añadir todos los atributos de
obj2
aobj1
lo que podría no ser lo que quiera si aún desea utilizar el no modificadoobj1
.Si está utilizando un marco que arruina todos sus prototipos, entonces debe ser más sofisticado con controles similares
hasOwnProperty
, pero ese código funcionará en el 99% de los casos.Función de ejemplo:
fuente
var merged = {...obj1, ...obj2}
.{...obj1, ...{animal: 'dog'}}
jQuery también tiene una utilidad para esto: http://api.jquery.com/jQuery.extend/ .
Tomado de la documentación de jQuery:
El código anterior mutará el objeto existente nombrado
settings
.Si desea crear un nuevo objeto sin modificar ninguno de los argumentos, use esto:
fuente
jQuery.extend(true,settings,override)
, que es importante si una propiedad en la configuración contiene un objeto y la anulación solo tiene parte de ese objeto. En lugar de eliminar las propiedades incomparables, la configuración profunda solo se actualizará donde exista. El valor predeterminado es falso.El Harmony ECMAScript 2015 (ES6) especifica
Object.assign
qué hará esto.El soporte actual del navegador está mejorando , pero si está desarrollando para navegadores que no tienen soporte, puede usar un polyfill .
fuente
Object.assign
tiene una cobertura bastante decente: kangax.github.io/compat-table/es6/…Object.assign({}, obj1, obj2)
Busqué en Google el código para fusionar las propiedades del objeto y terminé aquí. Sin embargo, como no había ningún código para la fusión recursiva, lo escribí yo mismo. (¿Quizás jQuery extend es recursivo, por cierto?) De todos modos, espero que alguien más lo encuentre útil también.
(Ahora el código no usa
Object.prototype
:)Código
Un ejemplo
Produce el objeto o3 como
fuente
Tenga en cuenta que
underscore.js
'sextend
-method hace esto en una línea:fuente
_({}).extend(obj1, obj2);
_.defaults(object, *defaults)
"Rellene las propiedades nulas e indefinidas en el objeto con valores de los objetos predeterminados y devuelva el objeto".var mergedObj = _.extend({}, obj1, obj2)
.Similar a jQuery extend (), tiene la misma función en AngularJS :
fuente
Necesito fusionar objetos hoy, y esta pregunta (y respuestas) me ayudaron mucho. Intenté algunas de las respuestas, pero ninguna de ellas se ajustaba a mis necesidades, por lo que combiné algunas de las respuestas, agregué algo y obtuve una nueva función de combinación. Aquí está:
Algunos usos de ejemplo:
fuente
merge({}, t1, { key1: 1 })
?Puede usar propiedades de propagación de objetos, actualmente una propuesta ECMAScript de etapa 3.
fuente
Las soluciones dadas deben modificarse para verificar
source.hasOwnProperty(property)
losfor..in
bucles antes de asignar; de lo contrario, terminará copiando las propiedades de toda la cadena de prototipos, lo que rara vez se desea ...fuente
Combinar propiedades de N objetos en una línea de código
Un
Object.assign
método es parte del estándar ECMAScript 2015 (ES6) y hace exactamente lo que necesita. (IE
no compatible)Lee mas...
El polyfill para admitir navegadores antiguos:
fuente
Objects.assign
devuelve un objeto combinado que las otras respuestas no. Ese es un estilo de programación más funcional.Los dos siguientes son probablemente un buen punto de partida. ¡lodash también tiene una función de personalización para esas necesidades especiales!
_.extend
( http://underscorejs.org/#extend )_.merge
( https://lodash.com/docs#merge )fuente
Por cierto, todo lo que estás haciendo es sobrescribir propiedades, no fusionar ...
Así es como realmente se fusionó el área de objetos de JavaScript: solo
to
se sobrescribirán las claves del objeto que no sean objetos en sífrom
. Todo lo demás se fusionará realmente . Por supuesto, puede cambiar este comportamiento para no sobrescribir nada que exista, solo sito[n] is undefined
, etc.Uso:
fuente
Aquí está mi puñalada que
Es corto :)
Ejemplo:
fuente
{}
como primer parámetro o si la función modifica el objeto original. Por lo tanto, si cambiadst = {}
adst = arguments[0]
él, cambiará el primer objeto que pase al objeto fusionadotoString.call(src) == '[object Object]'
para verificar si hay un objeto o no.typeof src
es mucho mejor. Además, transforma las matrices en objetos (por lo menos, tengo ese comportamiento en el último Chrome).Object.assign ()
ECMAScript 2015 (ES6)
Esta es una nueva tecnología, parte del estándar ECMAScript 2015 (ES6). La especificación de esta tecnología se ha finalizado, pero consulte la tabla de compatibilidad para conocer el uso y el estado de implementación en varios navegadores.
El método Object.assign () se utiliza para copiar los valores de todas las propiedades propias enumerables de uno o más objetos de origen a un objeto de destino. Devolverá el objeto de destino.
fuente
Para objetos no demasiado complicados, puede usar JSON :
¡Tenga en cuenta que en este ejemplo "} {" no debe aparecer dentro de una cadena!
fuente
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(/\}\{/, ", "));
Hay una biblioteca llamada
deepmerge
en GitHub : parece estar recibiendo algo de tracción. Es independiente, disponible a través de los administradores de paquetes npm y bower .Me inclinaría a usar o mejorar esto en lugar de copiar y pegar el código de las respuestas.
fuente
La mejor manera de hacerlo es agregar una propiedad adecuada que no sea enumerable mediante Object.defineProperty.
De esta manera, aún podrá iterar sobre las propiedades de sus objetos sin tener la "extensión" recién creada que obtendría si creara la propiedad con Object.prototype.extend.
Esperemos que esto ayude:
Una vez que tenga eso funcionando, puede hacer:
Acabo de escribir una publicación de blog al respecto aquí: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
fuente
Simplemente puede usar jQuery
extend
Ahora
obj1
contiene todos los valores deobj1
yobj2
fuente
jQuery.extend( target [, object1 ] [, objectN ] )
El prototipo tiene esto:
obj1.extend(obj2)
Hará lo que quieras.fuente
Object.prototype
y noObject
... Buena idea o no, esto es lo que hace elprototype.js
marco, y si lo está usando u otro marco que dependa de él,Object.prototype
ya se extenderáextend
.Object.prototype
?Object.extend
no interferirá con tus objetos, solo adjunta una función a unObject
objeto. Yobj1.extend(obj2)
no es forma correcta de la función de incendios, el usoObject.extend(obj1, obj2)
insted** Fusionar objetos es simple usando
Object.assign
o el...
operador de propagación **Los objetos se fusionan de derecha a izquierda, esto significa que los objetos que tienen propiedades idénticas a los objetos a su derecha se anularán.
En este ejemplo,
obj2.car
reemplazaobj1.car
fuente
Solo si alguien está usando la Biblioteca de cierre de Google :
Existe una función auxiliar similar para la matriz :
fuente
Extendí el método de David Coallier:
Si la anulación es falsa, no se anula ninguna propiedad, pero se agregarán nuevas propiedades.
Uso: obj.merge (combina ... [, anular]);
Aquí está mi código:
Ejemplos y casos de prueba:
Mi método igual se puede encontrar aquí: Comparación de objetos en JavaScript
fuente
En MooTools , hay Object.merge () :
fuente
En Ext JS 4 se puede hacer de la siguiente manera:
Ver merge (object): Object .
fuente
Wow ... esta es la primera publicación de StackOverflow que he visto con varias páginas. Disculpas por agregar otra "respuesta"
Este método es para ES5 y anteriores : hay muchas otras respuestas que abordan ES6.
No vi ninguna fusión de objetos "profundos" utilizando la
arguments
propiedad. Aquí está mi respuesta: compacta y recursiva , que permite pasar argumentos de objeto ilimitados:La parte que se comenta es opcional ... simplemente omitirá los argumentos pasados que no sean objetos (evitando errores).
Ejemplo:
fuente
Usando jQuery.extend () - Enlace
Usando _.merge () - Enlace
Usando _.extend () - Enlace
Usando Object.assign () ECMAScript 2015 (ES6) - Enlace
Salida de todos
fuente
Basado en la respuesta de Markus y vsync , esta es una versión ampliada. La función toma cualquier número de argumentos. Se puede usar para establecer propiedades en nodos DOM y hacer copias profundas de valores. Sin embargo, el primer argumento se da por referencia.
Para detectar un nodo DOM, se utiliza la función isDOMNode () (consulte la pregunta sobre desbordamiento de pila JavaScript isDOM: ¿cómo se verifica si un objeto JavaScript es un objeto DOM? )
Fue probado en Opera 11, Firefox 6, Internet Explorer 8 y Google Chrome 16.
Código
Algunos ejemplos
Establecer innerHTML y el estilo de un elemento HTML
Fusionar matrices y objetos. Tenga en cuenta que undefined puede usarse para preservar valores en la matriz / objeto de la izquierda.
Cualquier argumento que no sea un objeto JavaScript (incluido nulo) será ignorado. Excepto por el primer argumento, también se descartan los nodos DOM. Tenga en cuenta que las cadenas creadas como una nueva cadena () son, de hecho, objetos.
Si desea fusionar dos objetos en un nuevo suministro (sin afectar ninguno de los dos) {} como primer argumento
Editar (por ReaperSoon):
Para combinar también matrices
fuente
fuente
Debes usar los valores predeterminados de lodash
fuente
Con Underscore.js , para fusionar una matriz de objetos, haga lo siguiente:
En resultado de:
fuente