知识导向
- 对象的混入
- 类的混入
对象的混入
interface ObjA {
a: string
}
interface ObjB {
b: string
}
let obja: ObjA = {
a: 'a'
}
let objb: ObjB = {
b: 'b'
}
let objc: ObjA & ObjB = Object.assign(obja, objb)
console.log(objc);
// {a: "a", b: "b"}
类的混入
下面的代码演示了如何在TypeScript里使用混入。 后面我们还会解释这段代码是怎么工作的。
class ClassA {
public a: boolean = false
public funcA() {}
}
class ClassB {
public b: boolean = false
public funcB() {}
}
class ClassAB implements ClassA, ClassB {
public a: boolean = false
public b: boolean = false
public funcA() {}
public funcB() {}
constructor() {}
}
function Mixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
})
});
}
Mixins(ClassAB, [ClassA, ClassB])
const ab = new ClassAB()
console.log(ab);
理解这个例子
代码里首先定义了两个类,它们将做为mixins。 可以看到每个类都只定义了一个特定的行为或功能。 稍后我们使用它们来创建一个新类,同时具有这两种功能。
class ClassA {
public a: boolean = false
public funcA() {}
}
class ClassB {
public b: boolean = false
public funcB() {}
}
下面创建一个类,结合了这两个mixins。 下面来看一下具体是怎么操作的:
class ClassAB implements ClassA, ClassB {
}
首先应该注意到的是,没使用extends
而是使用implements
。 把类当成了接口,仅使用Disposable和Activatable的类型而非其实现。 这意味着我们需要在类里面实现接口。 但是这是我们在用mixin时想避免的。
class ClassAB implements ClassA, ClassB {
public a: boolean = false
public b: boolean = false
public funcA() {}
public funcB() {}
constructor() {}
}
最后,把mixins混入定义的类,完成全部实现部分。
Mixins(ClassAB, [ClassA, ClassB])
最后,创建这个帮助函数,帮我们做混入操作。 它会遍历mixins上的所有属性,并复制到目标上去,把之前的占位属性替换成真正的实现代码。
function Mixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
})
});
}
最后:
const ab = new ClassAB()
console.log(ab);
首先创建了两个类classA
和classB
,之后有创建了一个将前两个类作为接口实现的classAB
类,并在这个类里面将前两个类中所有的属性以及方法都使用了占位的方法做了定义,再在下面是用自定义的Mixins函数将前两个类中的所有的属性以及方法混合进了classAB
这个类中,使其之前的占位的属性已经方法都替换成了真正的代码,后面将classAB
实例化进行了测试。
网友评论