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