我有一个父类(super class)(基类)的两(2)个子类;如果我新建 B 和 C,我会得到两个实例 - 两者都通过扩展包含基类。
Question: Is it possible to place a Singleton restriction on the super class, and if so, how?
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's clone: What is your intention having a singleton pattern? Are you just in doubt if subclassing could generate multiple super class instances? Or do you try to prevent multiple subclass instances - super class should force that new C returns all the time the same C instance?
基类调用 MongoDB 并检索大量数据(如果只有一个类,则为基类)。当我有两个类扩展基类时,我不想调用 Mongo 并多次存储所有数据。 ATM 我使用单例模式来防止这种情况在独立类中发生,但我真的很想在有两个使用相同基类的类的情况下使用这种模式。
换句话来说, 我已经验证的问题正在发生:当我有两个类调用一个基类时,基类的构造函数被调用两次,并且 Mongo 被击中两次。 ATM 当通过扩展调用它时,我没有为基类设置单例模式。
现在我需要弄清楚如何在由多个类扩展的基类上应用单例模式。由于基类实际上是子类的同一个实例,我什至不知道这是否可能。
最佳答案
让我们首先生成一些测试输出到控制台。您应该在浏览器中运行它以获得全功能的控制台访问:
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
属性中的构造函数引用。如果它扩展了父类(super class),则原型(prototype)的原型(prototype)将与父类(super class)构造函数的 prototype
属性相同(请参阅下面的 __proto__
属性)。当你创建时
使用关键字 new 来创建 B 类的新实例,创建一个新对象并引用原型(prototype)
由构造函数分配给新对象的原型(prototype)。大多数浏览器在 __proto__ 属性中公开实例的原型(prototype)。但是,您应该通过 Object.getPrototype
方法访问它。
在检查器中,您可以使用 __proto__
属性来遍历树。
因此,你的问题的答案是:你不需要单例设计模式,因为相同的原型(prototype)
一旦在构造函数创建时实例化,每次使用关键字 new
创建新的时都会重复使用
实例。您可以在比较 Object.getPrototypeOf(Object.getPrototypeOf(b)) === Object.getPrototypeOf(Object.getPrototypeOf(c)) )
时看到示例中的行为。两个原型(prototype)链都引用相同的父类(super class)实例。
您应该阅读有关 JavaScript 原型(prototype)概念的更多文档。它可能看起来非常复杂和奇怪,特别是当您来自典型的 OOP 语言时,但它基于一个非常简单的设计。
关于javascript - ES6 : Restricting the Base Class to a Singleton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44221846/