javascript - ES6 : Restricting the Base Class to a Singleton

标签 javascript ecmascript-6 javascript-objects es6-class

我有一个父类(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/

相关文章:

javascript - 如何定位您单击并用于偏移的事件

javascript - 为什么文本在我的样式中闪烁?

javascript - 使用 es6 使用 chrome 进行调试

javascript - 如何在一个循环中组合/合并/相交两个对象数组?

javascript - jQuery 进度条不工作

javascript - 哪些 JavaScript 库将处理弹出窗口(例如 Meebo 或 Gmail 聊天窗口)?

javascript - 让普通 JavaScript ES6 等待 Ajax 完成

javascript - 过滤键并减少为嵌套结构

javascript - 如何获取具有重复属性名称的对象中的最大属性值?

Javascript - 使用字符串作为对象引用