blog icon indicating copy to clipboard operation
blog copied to clipboard

1.针对于extends koa2 导致babel转义时造成错误的处理方案

Open xtx1130 opened this issue 7 years ago • 2 comments

起因在于新建了一个类并继承了koa2,之后由于istanbul不支持async利用babel转义,引发的一系列血案

背景

Alt text   如图所示,babel在编译源代码的时候报错:Class constructor Application cannot be invoked without 'new'。
  对这个问题进行深究,发现是babel对 class a extends b{}而b是class声明且没有转义导致的,有兴趣的朋友可以试一下下面这段代码:

class b{};
b();

  这个会报同样的错误,究其原因就在于babel默认不会转义node_modlues中的文件,可能细心的朋友会发现,为什么koa1中没有报同样的错误?因为koa1构建类的时候用的是prototype,而koa2则是用的class。

解决方案

  这里给大家提供一个比较简单方便的解决方案,也就是在extends koa之前先对koa进行 new操作,再进行集成,代码如下:

const koa = new Koa();
function Extend(){
}
Object.assign(Extend.prototype,koa);
Extend.prototype.constructor = Extend;
Object.getOwnPropertyNames(koa.__proto__).forEach((key)=>{
	Extend.prototype[key] = koa.__proto__[key];
});
class Koas extends Extend {}

  轻松几步就可以跨过这个问题。在这里有一点需要注意的是 assign并不会拷贝__proto__上面的方法,class在实例化的时候,除了constructor中的方法和属性剩下的都会挂到__proto__上面,所以这里做了两步操作。

xtx1130 avatar Jul 12 '17 04:07 xtx1130

感觉这个继承写的有点问题啊。 Object.assign(Extend.prototype,koa); 这一句就把Koa实例属性也放到Extend原型对象上了,这应该不是"继承"的本意吧?

webjohnjiang avatar Jul 02 '19 15:07 webjohnjiang

@cuiyongjian 这里有点类似以前ecma3时代的“模拟继承”A.prototype = new B()。你所指的继承应该是ecma6里的extends这种真正的差异化继承吧。但是即使是extends这种继承方式,super也会把constructor中的属性继承到子类上的。

xtx1130 avatar Jul 03 '19 03:07 xtx1130