前端内参
搜索文档…
伍.1.6 用JavaScript实现接口
JavaScript并不支持接口(interface),然而在构建大型框架/库的时候,我们很需要想办法实现接口的特性:
  • 实现接口的类必须实现了接口中的方法;
  • 有办法检测到该类的实例的类型,并且这个类型和接口(约定的)类型值相等。

01.TypeScript的实现

由于JavaScript没有接口,因此,我将向你展示TypeScript如何实现此目的,因为TypeScript补全了JavaScript面向对象编程的能力,以和JavaScript面向原型的一个分支领域区别开来。
1
interface ShapeInterface {
2
area(): number
3
}
4
class Circle implements ShapeInterface {
5
let radius: number = 0
6
constructor (r: number) {
7
this.radius = r
8
}
9
10
public area(): number {
11
return MATH.PI * MATH.pow(this.radius, 2)
12
}
13
}
Copied!
在上面的示例中,展示了如何在TypeScript中实现此目标,但是TypeScript在后台将代码编译为纯JavaScript,而在已编译的代码中,由于JavaScript没有接口,因此也竟然没有给出接口有关的表现形式。真是扫兴啊!

02.JavaScript的实现

那么在JavaScript缺乏接口的情况下,我们如何实现这一目标呢?
通过函数组合可以实现。
首先,我们创建shapeInterface工厂函数,因为我们在谈论接口,所以我们的shapeInterface将使用函数组合出像接口一样抽象体。
什么是工厂函数?
在JavaScript中,函数若返回一个对象,且被返回的对象既不是构造函数、也不是某一个类,那么这该函数被称作工厂函数。
1
const shapeInterface = (state) => ({
2
type: 'shapeInterface',
3
area(){
4
if(state.area && typeof state.area === "function")
5
return state.area(state);
6
else
7
throw new Error("必须实现接口shapeInterface的方法area");
8
}
9
})
Copied!
然后我们让正方形(square)工厂函数实现上面的接口。
1
const square = (length) => {
2
const proto = {
3
length,
4
type : 'Square',
5
area : (args) => Math.pow(args.length, 2)
6
}
7
const basics = shapeInterface(proto)
8
const composite = Object.assign({}, basics)
9
return Object.assign(Object.create(composite), {length})
10
}
Copied!
接着调用工厂函数square后,结果应该是下面这样的:
1
const s = square(5)
2
console.log('OBJ\n', s)
3
console.log('PROTO\n', Object.getPrototypeOf(s))
4
s.area()
5
// 输出
6
//>> OBJ
7
//>> { length: 5 }
8
//>> PROTO
9
//>> { type: 'shapeInterface', area: [Function: area] }
10
//>> 25
Copied!
如此一来,我们可试着做一个产品经理要求的功能:计算面积之和的。其间可以检测具体的对象否有没有实现接口:
1
//计算面积之和
2
sum() {
3
const area = []
4
for (shape of this.shapes) {
5
//用Object.getPrototypeOf来检测类型
6
if (Object.getPrototypeOf(shape).type === 'shapeInterface') {
7
area.push(shape.area())
8
} else {
9
throw new Error('该对象不是接口shapeInterface的实例')
10
}
11
}
12
return area.reduce((v, c) => c += v, 0)
13
}
Copied!

03.结语

最后再次说一下,由于JavaScript不支持强类型语言之类的接口,上面的示例演示了我们如何模拟它,并不能十分完美的实现接口的各种特性。这也许是语言本身的局限,也有待你我探索。
最近更新 1yr ago