情况描述
项目是默认使用webpack编译采用es6模块处理方案
出现了以下错误
以下是我写的测试类
A.ts
import {B} from "./b.js";
export class A {
static getInstance() {
if (!this._instance) {
this._instance = new A();
}
return this._instance;
}
flush() {
console.log("----------------flush-------------------");
}
a() {
console.log("----------------flush-------------------");
B.getInstance().zuo();//这一行的问题
}
}
B.ts
import {A} from "./a.js";
export class B extends A {
static getInstance() {
if (!this._instance) {
this._instance = new B();
}
return this._instance;
}
zuo() {
console.log("-----------13 zuo-----------------------");
A.getInstance().flush();
}
}
使用
import {A} from './js/a.js';
(new A()).flush();
原因分析
//省略部分代码
...([function (e, t, n) {
"use strict";
n.r(t);
class o extends r {//r在下面才定义
static getInstance() {
return this._instance || (this._instance = new o), this._instance
}
zuo() {
console.log("-----------13 zuo-----------------------"), r.getInstance().flush()
}
}
class r {
static getInstance() {
return this._instance || (this._instance = new r), this._instance
}
flush() {
console.log("----------------flush-------------------")
}
a() {
console.log("----------------flush-------------------"), o.getInstance().zuo()
}
}(new r).flush()
}]);
看webpack输出来的js代码,就可以看出问题,
A和B循环引用,最大的错误是父类A使用了子类B,导致webpack把代码编译成JavaScript代码时,把B误认为是应该先定义,结果在A还没有初始化是就在extends后要使用它,才会导致报错。
模块循环引用,在项目越做越大,人员越来越复杂的情况下是不可避免的,其实不带继承关系,这样的循环引用是不会问题的。
解决方案
将原来直接调用单例改为属性赋值方式,如下:
private b:B;
a(){
this.b&&this.b.zuo();
}