Quiero crear una combinación que cree objetos anidados en el objeto con el que se mezcla.
Por ejemplo
const mixin = { top: { middle: { bottom: () => { console.log(`Hello ${this.name}`); } } } }; const objectToBeMixed = { name: 'Fred Bloggs' }; Object.assign(objectToBeMixed, mixin); objectToBeMixed.top.middle.bottom(); // Prints "Hello Fred Blogs"¿Alguien tiene una idea de cómo hacer esto, de modo que "esto" esté vinculado al objectToBeMixed?
Así no es como implementas mixins. En lugar de usar un objeto simple, use una función que acepte el context y fusione los objetos:
const mixin = context => Object.assign(context, { top: { middle: { bottom: () => { console.log(`Hello ${context.name}`); } } } }); const objectToBeMixed = { name: 'Fred Bloggs' }; mixin(objectToBeMixed); objectToBeMixed.top.middle.bottom(); // Prints "Hello Fred Blogs"Hay un par de posibles problemas allí:
Al usar una función de flecha, se está cerrando sobre this . Pero this que está cerrando no se referirá al objeto que está mezclando. Hay varias formas de resolver eso ( bind , etc.), pero implican hacer una copia profunda de la mezcla.
Si va a usar esa combinación más de una vez, probablemente quiera esa copia profunda por otra razón, aunque, por supuesto, depende de su caso de uso. Si el código crea propiedades en esos objetos y no son copias profundas, eso creará una conversación cruzada entre las instancias con las que lo está usando. (Si no va a hacer una copia profunda, freeze los objetos en el mixin para evitar la diafonía creando propiedades en ellos).
Dado que lo más seguro es tener objetos separados para cada objetivo, escribiría una función que crea los objetos de mezcla y los aplica, con la función bottom cerrándose sobre el parámetro objetivo. Algo como esto:
function applyX(target) { const mixin = { top: { middle: { bottom() { console.log(`Hello ${target.name}`); } } } }; return Object.assign(target, mixin); } const objectToBeMixed = { name: "Fred Bloggs" }; applyX(objectToBeMixed); objectToBeMixed.top.middle.bottom(); // Prints "Hello Fred Bloggs"