Antecedentes
Tengo una función que toma un config
objeto como argumento. Dentro de la función, también tengo default
objeto. Cada uno de esos objetos contiene propiedades que esencialmente funcionan como configuraciones para el resto del código dentro de la función. Para evitar tener que especificar todas las configuraciones dentro del config
objeto, uso el extend
método de jQuery para completar un nuevo objeto, settings
con los valores predeterminados del default
objeto si no se especificaron en el config
objeto:
var config = {key1: value1};
var default = {key1: default1, key2: default2, key 3: default 3};
var settings = $.extend(default, config);
//resulting properties of settings:
settings = {key1: value1, key2: default2, key 3: default 3};
Problema
Esto funciona muy bien, pero me gustaría reproducir esta funcionalidad sin la necesidad de jQuery. ¿Existe un medio igualmente elegante (o cercano a) para hacer esto con javascript simple?
Editar: Justificación no duplicada
Esta pregunta no es un duplicado de la pregunta " ¿Cómo puedo fusionar propiedades de dos objetos JavaScript de forma dinámica? ". Mientras que esa pregunta simplemente quiere crear un objeto que contenga todas las claves y valores de dos objetos separados, quiero abordar específicamente cómo hacer esto en caso de que ambos objetos compartan algunas claves, pero no todas, y qué objeto tendrá prioridad ( el predeterminado) para el objeto resultante en caso de que haya claves duplicadas. E incluso más específicamente, quería abordar el uso del método de jQuery para lograr esto y encontrar una forma alternativa de hacerlo sin jQuery. Si bien muchas de las respuestas a ambas preguntas se superponen, eso no significa que las preguntas en sí sean las mismas.
fuente
jQuery.isPlainObject
yjQuery.isFunction
Respuestas:
Para obtener el resultado en su código, haría lo siguiente:
Tenga en cuenta que la forma en que utilizó extender allí modificará el objeto predeterminado. Si no quieres eso, usa
Una solución más robusta que imita la funcionalidad de jQuery sería la siguiente:
fuente
Puede utilizar Object.assign.
Copia los valores de todas las propiedades propias enumerables de uno o más objetos de origen a un objeto de destino y devuelve el objeto de destino.
Funciona en todos los navegadores de escritorio excepto IE (pero incluido Edge). Ha mitigado el soporte móvil.
Compruébelo usted mismo aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Acerca de la copia profunda
Sin embargo, Object.assign no tiene la opción profunda que tiene el método extend de jQuery.
Nota: generalmente puede usar JSON para un efecto similar aunque
fuente
Puede usar el operador de propagación ECMA 2018 en literales de objeto ...
Soporte de BabelJS para navegadores más antiguos
fuente
Este es mi enfoque ligeramente diferente con una copia profunda que se me ocurrió al intentar eliminar una dependencia de jQuery. Está diseñado principalmente para ser pequeño, por lo que es posible que no tenga todas las funciones que uno espera. Debe ser totalmente compatible con ES5 (a partir de IE9 debido al uso de Object.keys ):
Puede preguntarse qué hace exactamente la quinta línea ... Si obj2.key es un objeto literal (es decir, si no es de un tipo ordinario) llamamos recursivamente a extender sobre él. Si una propiedad con ese nombre aún no existe en obj1, primero la inicializamos a un objeto vacío. De lo contrario, simplemente establecemos obj1.key en obj2.key.
Estas son algunas de mis pruebas de mocha / chai que deberían demostrar que los casos comunes funcionan aquí:
Me alegraría recibir comentarios o sugerencias sobre esta implementación. ¡Gracias por adelantado!
fuente
Puede recorrer las propiedades de Object usando
for
declaración.fuente
a
. Aunque no está en el ejemplo, en$.extend
realidad funciona de esa manera, fusionando todas las propiedades de todos los objetos.Prefiero este código que usa mi forEachIn genérico y no destruye el primer objeto:
Si realmente desea fusionar cosas en el primer objeto, puede hacer:
fuente
Me ayuda mucho cuando desarrollo con javascript puro.
fuente
El enfoque de Ivan Kuckir también se puede adaptar para crear un nuevo prototipo de objeto:
fuente