mixin
a mixin is a object containing methods that can be used by other objects without a need to inherit from it.
- replit ⟩ mixin 
const { log } = console;
// -------------- Object.assign --------------
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
// -------------- Mixins --------------
// ⭐ mixin (similar to Swift protocols)
let canSayHi = {
    sayHi() { log(`Hello ${this.name}!`) },
    sayBye() { log(`Bye ${this.name}!`) },
};
// User
class User {
    constructor(name) {
        this.name = name;
    }
}
// -------------------------------------------------
// ⭐ copy all enumerable own members from mixin(s)
//    to `User.prototype`, NOT `User` itself.
//
//             ╭ ⭐️ target ─╮  ╭source╮
Object.assign( User.prototype, canSayHi );
//
// -------------------------------------------------
// now User can say hi
new User("Dude").sayHi();          // Hello Dude!
[
    // same object    
    target,                        // { a: 1, b: 4, c: 5 }
    returnedTarget,                // { a: 1, b: 4, c: 5 }
    target === returnedTarget,     // true
    
    // same function
    User.prototype.sayHi === canSayHi.sayHi,    // true
].forEach(x => log(x));in Object.assign(),
- null or undefined target will trigger TypeError. 
- null or undefined sources will be ignored. 
const str  = 'abc';
const bool = true;
const num  = 10;
const sym  = Symbol('foo');
// • primitives wrapped
// • null and undefined (sources) ignored
const obj = Object.assign({}, str, null, bool, undefined, num, sym);
// only "string wrappers" have own enumerable properties.
console.log(obj);     // { "0": "a", "1": "b", "2": "c" }- replit ⟩ mixin object into "number"? 
const { log } = console;
// ----------------------------------------------
// ❌ assign object to "null" (Error)
// ⛔ TypeError: 
//    Cannot convert undefined or null to object
//
//    let o1 = Object.assign(null, {a: 1});
//                           ^^^^  <----
// ----------------------------------------------
// ✅ assign object to "number" (it's OK)
//    "number" is wrapped to object.
let o2 = Object.assign(3, {a: 1});
let n = 5;
// --------------------------------------------
// ⛔ TypeError:
//    Cannot create property 'b' on number '5'
//
//    n.b = 3;
//    ^  <----
// --------------------------------------------
[
    o2,                      // [Number: 3] { a: 1 }
    typeof o2,               // 'object'    (⭐ NOT 'number'❗)
    o2 instanceof Number,    // true        (⭐ still a `Number`❗)
    o2.a,                    // 1
    
    o2 ==  3,    // true
    o2 === 3,    // false        (⭐ NOT the same thing❗)
    3  === 3,    // true
    o2 + 4,      // 7
    
    n + n.b,     // NaN          ( 5 + undefined )
    typeof n,    // 'number'
    
].forEach(x => log(x));- Object.assign() copies all enumerable own properties from one or more source objects to a target object, and returns the modified target object. 
- similar to clone(obj). 
- Object.assign() uses getter/setter to achieve its goal. 
- here are for Google Apps Script objects. 
- obj.prop(path) - access object's property by its path. 
- SheetMethods - mixin for Google Apps Script Sheet objects. 
Last updated
Was this helpful?