ES2015孙子继承旁路链与巴贝尔转换器

时间:2018-04-17 09:19:35

标签: javascript ecmascript-6 babeljs

我正在使用ES2015 Babel transpiler。

我遇到了一些非常奇怪的事情。实际的课程很复杂。所以我将使用一个我没有实际运行的例子。这是一个时间问题,我不知道我是否可以使用以下代码完全复制它,但这个想法是这样的:



class A {
  static instance() {
    if (!A._instance) {
       A._instance = new A();
    }
    return A._instance;
  }

  foo() {
    console.log('A')
  }
}

class B extends A {
  static instance() {
    if (!B._instance) {
       B._instance = new B();
    }
    return A._instance;
  }

  foo() {
    console.log('B')
    super.foo();
  }
}

class C extends B {
  static instance() {
    if (!C._instance) {
       C._instance = new C();
    }
    return C._instance;
  }

  foo() {
    console.log('C')
    super.foo();
  }
}

// Somewhere else
class User {
  static bar() {
    C.instance().foo(); // Sometimes, this calls B.foo() directly, C.foo() is bypassed!
  }
}

// create A._instance first
A.instance().foo();

// now C will inherint _instance from B which inherits is from A.
User.bar()




我在一个香草Cordova项目中使用Gulp运行ES6转换器。但是,当我尝试在桌面Chrome中运行它时,同样的事情发生了。

有时C.instance().foo()实际上并未调用C中定义的foo,而是调用B.instance().foo()。有时",我的意思是当我加载登录页面时,我可以在Chrome中100%复制它,并像往常一样登录。但如果检查了应用程序的Remember me选项,并且用户直接登录到主页面,我永远无法复制它。这似乎是一个时间问题。但我不知道究竟是什么。有线索吗?

编辑1: 代码文件通过在index.html中单独使用普通的嵌入式脚本标记包含在项目中。

1 个答案:

答案 0 :(得分:3)

实际上问题如下。

如果您首先调用父类instance方法,则由于继承,您的子类也将具有_instance属性。您需要检查您的子类是否具有名为_instance的属性。



class A {
  /**
   * OOP all the way. Let's define static method that 
   * checks for own property `_instance`
   */
  static hasOwnInstance() {
    return Object.prototype.hasOwnProperty.call(this, '_instance')
  }
  static instance() {
    // rewrite to use this instead of class name
    if (!this.hasOwnInstance()) { // now we check only own properties
       this._instance = new this();
    }
    return this._instance;
  }

  foo() {
    console.log('A')
  }
}

class B extends A {
  /* Now safe to simply inherit implementation from A
  static instance() {
    if (!B.hasOwnInstance()) {  // now we check only own properties
       B._instance = new B();
    }
    return B._instance;
  } */

  foo() {
    console.log('B')
    super.foo();
  }
}

class C extends B {
  foo() {
    console.log('C')
    super.foo();
  }
}

// Somewhere else
class User {
  static bar() {
    C.instance().foo(); // Sometimes, this calls B.foo() directly, C.foo() is bypassed!
  }
}

// call B.instance first
console.log('B.foo')
B.instance().foo();

console.log('C.foo')
User.bar()