我正在使用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中单独使用普通的嵌入式脚本标记包含在项目中。
答案 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()