我正在评估一种在JavaScript中使用称为Monostate的Singleton模式的方法。

我有一些类似以下的代码:

class Boss {
  get name() { return Boss._name }
  set name(value) {
    Boss._name = value;
  }

  get age() { return Boss._age }
  set age(value) {
    Boss._age = value
  }

  toString() {
    return `
      Boss' name is ${this.name}
      and he is ${this.age} years old.
    `
  }
}

Boss._age = undefined;
Boss._name = undefined;

但是我对类作用域和实例作用域之间的区别并不深刻理解

我的意思是如果我做以下事情:
let boss = new Boss();
boss.name = 'Bob';
boss.age = 55;

let boss2 = new Boss();
boss2.name = 'Tom';
boss2.age = 33;

console.log(boss.toString());
console.log(boss2.toString());

我将始终获得名称为Tom的第二个实例的数据,但是为什么呢?

Boss' name is Tom and he is 33 years old.

最佳答案

出现这种现象的原因是由于Boss实例引用同一Boss对象来设置和读取其值。 Boss的实例在_name上设置_ageBoss值。从这些实例属性读取时,将返回最后一个值集。

您可以通过Boss._name的值(每次Boss实例设置其名称时都会更改)来看到此值。在boss.name = 'Bob'之后,Boss._name的值将为'Bob'。设置boss2.name = 'Tom'后,Boss._name的值将为'Tom'

我添加了一个片段,希望可以更好地显示令人烦恼的行为。在下面的方案中,boss1boss2拥有自己的存储空间,而boss3boss4共享它们的存储空间(您将Boss对象用作存储空间)。

class Boss {
  constructor(storage) {
    this.storage = storage || {};
  }

  get name() {
    return this.storage.name;
  }

  set name(value) {
    this.storage.name = value;
  }
}

var boss1 = new Boss(),
    boss2 = new Boss(),
    sharedStorage = {},
    boss3 = new Boss(sharedStorage),
    boss4 = new Boss(sharedStorage);

boss1.name = "a";
boss2.name = "b";
boss3.name = "c";
boss4.name = "d";

console.log(boss1.name, boss2.name, boss3.name, boss4.name);

10-06 11:37