混入 Mixins

63 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

介绍

除了传统的面向对象继承方式,还流行一种通过可重用组件创建类的方式,就是联合另一个简单的代码,你可能在Scala等语言里对mixins及其特性已经很熟悉了,但是在javascript中也是很流行的

作用

解决TS中继承一次只继承一个类的问题

注意点

类的混入不能混入属性名

js实现组合的方式,可以利用Object的assign方法来实现


let nameObj = { name: '骚帮' }
let ageObj = { age: 19 }

Object.assign(nameObj, ageObj)
console.log(nameObj, ageObj)

js中类的继承只能继承一个类,但是可以实现多个接口


class Name {
    name: string = 'saobang'
    getName() {
        console.log('我是骚帮')
    }
}
class Age {
    age: number = 12
    getAge() {
        console.log('我今年12岁了')
    }
}

class Person implements Name,Age{
    name:string;
    age:number;
    getAge(): void {
        
    }
    getName(): void {
        
    }
}

混入方法

混入的原理实际上就是在目标对象的原型对象上添加要混入的对象的原型对象上的属性和方法, Object.getOwnPropertyNames方法获取目标原型对象上自身的所有属性,然后遍历,把这些属性的值一一拷贝到目标对象的原型对象上,这样一来,目标对象的原型对象上就有了要混入的对象的所有的属性和方法,



class Name {
    name: string = 'saobang'
    getName() {
        console.log('我是骚帮')
    }
}
class Age {
    age: number = 12
    getAge() {
        console.log('我今年12岁了')
    }
}


function mixins(target: any, ...from: any[]) {
    from.forEach(item => {
        Object.getOwnPropertyNames(item.prototype).forEach(name => {
            target.prototype[name] = item.prototype[name]
        })
    })
    return target
}

let Person = mixins(class {

}, Name, Age)
let p = new Person()
p.getAge();
p.getName()
console.log(p)

上面这种写法的最终结果如下


class Person {
    name: string = 'saobang'
    getName() {
        console.log('我是骚帮')
    }
    age: number = 12
    getAge() {
        console.log('我今年12岁了')
    }
}

这么写会有类型错误,因为编辑器不会自动给类型增加属性和方法,这个点还是需要一点优化啊



class Name {
    name: string = 'saobang'
    getName() {
        console.log('我是骚帮')
    }
}
class Age {
    age: number = 12
    getAge() {
        console.log('我今年12岁了')
    }
}

class Person {
 
}
function mixins(target: any, ...from: any[]) {
    from.forEach(item => {
        Object.getOwnPropertyNames(item.prototype).forEach(name => {
            target.prototype[name] = item.prototype[name]
        })
    })
}

mixins(Person, Name, Age)
let p = new Person()
p.getAge();
p.getName()
console.log(p)