Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var emptyFunction = () => {}
- /**
- * creates a new constructor function with `objects` merged in its prototype.
- * to prevent unwanted errors when calling `super()` a child class, the
- * prototype is actually a proxy returning **or** the actual method, or an
- * empty function.
- *
- * as the proxy gets the same shape as the initial object, the prototype chain
- * actually receives the present methods.
- *
- * @param {Object} ...objects
- * @returns {Function}
- */
- function mixins(...objects) {
- var proto = {}
- objects.forEach((object) => {
- if(object == null || object === false) {
- return
- }
- for(let methodName in object) {
- let previousMethod = proto[methodName]
- let method = object[methodName]
- let actualMethod = method
- if(previousMethod) {
- // if mixins have multiple methods, we merge them
- actualMethod = function(...args){
- previousMethod.apply(this, args)
- method.apply(this, args)
- }
- }
- proto[methodName] = actualMethod
- }
- })
- function ComposedClass(){
- ComposedClass.prototype.constructor.apply(this, arguments)
- }
- ComposedClass.prototype = new Proxy(proto, {
- get(object, methodName) {
- return proto[methodName] || emptyFunction
- },
- set() {
- throw new TypeError()
- }
- })
- return ComposedClass
- }
- const A = {
- constructor() {
- this.name = "defaultName"
- },
- getName() {
- return this.name
- },
- setName(name) {
- this.name = name
- }
- }
- const B = {
- constructor() {
- this.foo = "bar"
- }
- }
- class Test extends mixins(A, B) {
- constructor() {
- super()
- }
- test() {
- super() // doesn't throw, as the proxy returns an empty function
- return "foo"
- }
- }
- const t = new Test()
- console.log(t.name)
- console.log(t.foo)
- console.log(t.test())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement