es6模块报错Uncaught ReferenceError: Cannot access '.' before initialization

情况描述

项目是默认使用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();
    }

你可能感兴趣的:(webpack,javascript,前端问题)