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();
    }
發佈了33 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章