gpt4 book ai didi

javascript - 在 es6 中扩展单例类

转载 作者:行者123 更新时间:2023-11-30 11:14:31 25 4
gpt4 key购买 nike

我需要在 JavaScript 中扩展一个单例类。

我面临的问题是我得到了我正在扩展的类实例,而不是只得到类的方法。

我试图删除 super 以不获取实例,但随后出现错误

Must call super constructor in derived class before accessing 'this' or returning from derived constructor

代码示例:

let instanceA = null;
let instanceB = null;

class A {
constructor(options) {
if (instanceA === null) {
this.options = options;
instanceA = this;
}
return instanceA;
}
}

class B extends A {
constructor(options) {
if (instanceB === null) {
super()
console.log('real class is ' + this.constructor.name)
this.options = options
instanceB = this;
}
return instanceB;
}
}

const a = new A({
i_am_a: "aaaaaa"
});

const b = new B({
i_am_b: "bbbbbb"
}) // this change a

console.log(b.options)

console.log(a.options)

最佳答案

所以,首先这里有一个误解:

I have tried to remove super to not get the instance but then I got an error

super() 在子类的已创建实例上调用父类的构造函数(即 this 所引用的内容)。它不返回父类实例。 See here了解更多信息。

所以,调用super()根本就没有违反父类的单例属性。如果正确实现,它很可能只构建一次。


考虑到这一点,您应该稍微改进一下代码。

一个明智的改变是从构造函数中删除实例管理。一种解决方案是使用静态构造函数,如果实例不存在则创建单例或返回创建的实例。

另一种方法是将参数丢给单例类构造函数。将参数传递给应该实例化一次的类并没有什么意义(你永远不会再对构造函数参数做任何事情)。您可以立即创建单例的参数属性。这是一个 SO answer支持 Java 单例的这一点。

带有静态构造函数且不带参数的完整示例如下所示:

let instanceA = null;
let instanceB = null;

let counters = { A: 0, B: 0 }; // count class instantiations

class A {
static getInstance() {
if (instanceA === null) {
instanceA = new A();
}
return instanceA;
}
whoami() {
const name = this.constructor.name;
return `${name} #${counters[name]}`;
}
constructor() {
counters[this.constructor.name] += 1;
}
}

class B extends A {
static getInstance() {
if (instanceB === null) {
instanceB = new B();
}
return instanceB;
}
constructor() {
super();
}
}

const a1 = A.getInstance();
const a2 = A.getInstance();
const a3 = A.getInstance();
const b1 = B.getInstance();
const b2 = B.getInstance();
const b3 = B.getInstance();
console.log(a1.whoami());
console.log(a2.whoami());
console.log(a3.whoami());
console.log(b1.whoami());
console.log(b2.whoami());
console.log(b3.whoami());

请注意,BA 继承了 whoami,并且构造函数调用计数器的增量永远不会超过 1。

显然,使用这种方法不能保证每个类的单例属性都成立,除非只使用静态构造函数来生成实例(因为构造函数仍然可以访问)。不过,我认为这是一个很好的妥协。

关于javascript - 在 es6 中扩展单例类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52188364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com