Javascript ES2015孙辈继承旁路链,带巴别塔transpiler

Javascript ES2015孙辈继承旁路链,带巴别塔transpiler,javascript,ecmascript-6,babeljs,Javascript,Ecmascript 6,Babeljs,我使用的是ES2015巴贝尔transpiler 我遇到了一些非常奇怪的事情。实际的类是复杂的。所以我将使用一个我没有实际运行的示例。这是一个时间问题,我不知道是否可以用以下代码准确地复制它,但想法是这样的: A类{ 静态实例(){ 如果(!一个._实例){ A.。_实例=新的A(); } 返回一个U实例; } foo(){ console.log('A') } } B类扩展了A类{ 静态实例(){ 如果(!B._实例){ B._实例=新的B(); } 返回一个U实例; } foo(){ co

我使用的是ES2015巴贝尔transpiler

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

A类{
静态实例(){
如果(!一个._实例){
A.。_实例=新的A();
}
返回一个U实例;
}
foo(){
console.log('A')
}
}
B类扩展了A类{
静态实例(){
如果(!B._实例){
B._实例=新的B();
}
返回一个U实例;
}
foo(){
console.log('B')
super.foo();
}
}
C类扩展到B类{
静态实例(){
if(!C.\u实例){
C._实例=新的C();
}
返回C.\u实例;
}
foo(){
console.log('C')
super.foo();
}
}
//其他地方
类用户{
静态条(){
C.instance().foo();//有时,它直接调用B.foo(),而C.foo()则被忽略!
}
}
//首先创建一个U实例
A.instance().foo();
//现在C将从B中继承一个从A继承的实例。

User.bar()
实际上问题如下

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

A类{
/**
*一直以来都是面向对象的。让我们定义静态方法
*检查自己的属性“%u”实例`
*/
静态hasOwnInstance(){
return Object.prototype.hasOwnProperty.call(此'.\u实例')
}
静态实例(){
//重写以使用此名称而不是类名
如果(!this.hasOwnInstance()){//现在我们只检查自己的属性
this._instance=newthis();
}
返回此。\u实例;
}
foo(){
console.log('A')
}
}
B类扩展了A类{
/*现在可以安全地从
静态实例(){
如果(!B.hasOwnInstance()){//现在我们只检查自己的属性
B._实例=新的B();
}
返回B.\u实例;
} */
foo(){
console.log('B')
super.foo();
}
}
C类扩展到B类{
foo(){
console.log('C')
super.foo();
}
}
//其他地方
类用户{
静态条(){
C.instance().foo();//有时,它直接调用B.foo(),而C.foo()则被忽略!
}
}
//先打电话给B.instance
console.log('B.foo')
B.instance().foo();
console.log('C.foo')

User.bar()
实际上问题如下

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

A类{
/**
*一直以来都是面向对象的。让我们定义静态方法
*检查自己的属性“%u”实例`
*/
静态hasOwnInstance(){
return Object.prototype.hasOwnProperty.call(此'.\u实例')
}
静态实例(){
//重写以使用此名称而不是类名
如果(!this.hasOwnInstance()){//现在我们只检查自己的属性
this._instance=newthis();
}
返回此。\u实例;
}
foo(){
console.log('A')
}
}
B类扩展了A类{
/*现在可以安全地从
静态实例(){
如果(!B.hasOwnInstance()){//现在我们只检查自己的属性
B._实例=新的B();
}
返回B.\u实例;
} */
foo(){
console.log('B')
super.foo();
}
}
C类扩展到B类{
foo(){
console.log('C')
super.foo();
}
}
//其他地方
类用户{
静态条(){
C.instance().foo();//有时,它直接调用B.foo(),而C.foo()则被忽略!
}
}
//先打电话给B.instance
console.log('B.foo')
B.instance().foo();
console.log('C.foo')

User.bar()
我已将您的代码转换为可运行的示例。发丝由巴贝尔完成。它没有显示所描述的错误。我建议您创建一个最小的示例来演示问题和传输后的代码。我添加了可能的场景,可能会演示您描述的问题。:)如果不只是恢复我的更改:)单例已损坏。具有继承性的单例情况甚至更糟。不要试图这么做。@YuryTarabanko哇,非常感谢!我不知道我能做到这一点。@Bergi所说的破碎对你来说是破碎的设计吗?或者你的意思是它在语言中被破坏了?很多时候我不知道还能用什么。我已经把你的代码转换成了可运行的例子。发丝由巴贝尔完成。它没有显示所描述的错误。我建议您创建一个最小的示例来演示问题和传输后的代码。我添加了可能的场景,可能会演示您描述的问题。:)如果不只是恢复我的更改:)单例已损坏。具有继承性的单例情况甚至更糟。不要试图这么做。@YuryTarabanko哇,非常感谢!我不知道我能做到这一点。@Bergi所说的破碎对你来说是破碎的设计吗?或者你的意思是它在语言中被破坏了?很多时候我不知道还可以使用什么。为什么不继承
实例
方法,使用
this
而不是相应的类名呢?@Bergi Yep一个更好的选择是重写
实例
以使用
this
。以前我在使用ES5时做过同样的事情,为什么没有发生这种情况?我只是幸运吗?我一直认为
C.\u实例
B.\u实例
是独立的名称空间。毕竟,它是
函数C()
函数B()
@huggie“我一直认为C.\u实例和B.\u实例是独立的名称空间。”它们有单向“连接”。C.[prototype]]设置为B。您稍后添加到
B
的所有内容都将通过prototype链在
C
中立即可用。为什么不使用
thi继承
实例
方法呢