我有一个超级类(基类)的两(2)个子类;如果我有新的B和C,我会得到两个实例 - 两者都包含扩展的基类。
问题:是否可以对super进行Singleton限制 上课,如果有,怎么样?
class A {
constructor(id) {
// => I don't want to make this call (2) times,
// once for B and again for C.
let {
firstName: this._FirstName
} = CollectionName.findOne({userId: id});
}
}
export class B extends A {
constructor(id) {
super(id);
}
get FirstName() {
return this._FirstName;
}
}
export class C extends A {
constructor(id) {
super(id);
}
get FirstName() {
return this._FirstName;
}
}
import { B, C } from 'imports/server/a-b-c.js'
const b = new B('123')
const c = new B('456')
const FirstNameB = b.FirstName;
const FirstNameC = c.FirstName;
编辑:
我将尝试回答这些问题。
@ Quasimodo克隆:你有什么打算使用单身人士模式?如果子类化可以生成多个超类实例,您是否有疑问?或者您是否尝试阻止多个子类实例 - 超类应该强制新C一直返回相同的C实例?
基类调用MongoDB并检索大量数据(如果只有一个类是基类)。当我有两个类扩展基类时,我不想呼叫Mongo并多次存储所有数据。 ATM我使用单例模式来防止这种情况发生在单独的类中,但在我有两个使用相同基类的类的情况下,我真的很喜欢使用这种模式。
以不同的方式说, 我已经验证的问题正在发生:当我有两个类调用一个基类时,基类的构造函数被调用两次,而Mongo被调用两次。 ATM当我通过扩展调用时,我没有为基类设置单例模式。
现在我需要弄清楚如何在由多个类扩展的基类上应用单例模式。由于基类实际上是子类的同一个实例,我甚至不知道这是否可行。
答案 0 :(得分:1)
让我们首先向控制台生成一些测试输出。您应该在浏览器中运行它以获得功能齐全的控制台访问权限:
class Base
{
constructor(value)
{
this.prop = value;
}
funcBase() {}
}
class B extends Base
{
constructor(value)
{
super(value);
}
funcB() {}
}
class C extends Base
{
constructor(value)
{
super(value);
}
funcC() {}
}
let
b = new B('instance b'),
b2= new B('instance b'),
c = new C('instance c')
;
// Do instances of class B and class C have the identical prototype?
console.log( 'proto(b) === proto(c)',
Object.getPrototypeOf(b) === Object.getPrototypeOf(c) );
// false
// Do the prototypes of those instances b and c have the idendical prototype?
console.log( 'proto-proto(b) === proto-proto(c)',
Object.getPrototypeOf(Object.getPrototypeOf(b)) === Object.getPrototypeOf(Object.getPrototypeOf(c)) );
//true
// Do two instances of class B have the identical prototype?
console.log( 'proto(b) === proto(b2)',
Object.getPrototypeOf(b) === Object.getPrototypeOf(b2) );
// true
// Is b's prototype's prototype identical to Base.prototype?
console.log( 'proto-proto(b) === Base.prototype',
Object.getPrototypeOf(Object.getPrototypeOf(b)) === Base.prototype );
//true
// Let's inspect the prototypes in the console
// What is the prototype of b
console.log( Object.getPrototypeOf(b) ); // an instance with constructor B() and funcB()
// What is the b's prototype's prototye?
console.log( Object.getPrototypeOf(Object.getPrototypeOf(b)) ); // an instance with constructor Base() and funcBase()
// Inspect constructor function B()
try { console.dir( B ); }
catch(e) { console.log( B ); } // [right click the "B" in the output and open in variable inspector]

如您所见,class
关键字实际上为您编译了构造函数和原型实例。
该实例由其prototype
属性中的构造函数引用。如果它扩展了一个超类,那么原型的原型将与超类构造函数的prototype
属性相同(参见下面的__proto__
属性)。当你创建
使用关键字new
创建B类的新实例,创建一个新对象并引用原型
由构造函数分配给新对象的原型。大多数浏览器在__proto__
属性中公开实例的原型。但是,您应该通过Object.getPrototype
方法访问它。
在检查器中,您可以使用__proto__
属性遍历树。
因此,您的问题的答案是:您不需要单一设计模式,因为相同的原型
一旦在构造函数创建时实例化,每次使用关键字new
创建新的时,都会重复使用
实例。比较Object.getPrototypeOf(Object.getPrototypeOf(b)) === Object.getPrototypeOf(Object.getPrototypeOf(c)) )
时,您可以在示例中看到行为。两个原型链都引用相同的超类实例。
您应该阅读有关JavaScript原型概念的更多文档。它可能看起来非常复杂和奇怪,特别是当你来自典型的OOP语言时,它基于一个非常简单的设计。