3

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

我有一些如下代码:

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;

但是我并没有深入理解 Class 范围与 Instance 范围之间的区别

我的意思是,如果我进行以下操作:

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());

我总是会用 name 获得第二个实例的数据Tom,但为什么呢?

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

3 回答 3

2

发生这种行为的原因是实例Boss引用同一个Boss对象来设置和读取它们的值。Boss设置_name_age值 on的实例Boss。从这些实例属性中读取时,将返回最后一个值集。

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);

于 2019-07-10T16:34:57.707 回答
0

使用this而不是类名Boss来引用类定义中的对象实例:

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

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

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

const b1 = new Boss();
b1.name = 'Tom';
b1.age = 55;

const b2 = new Boss();
b2.name = 'Bill';
b2.age = 33;

console.log(b1.toString());
console.log(b2.toString());

Boss您真正需要实例时,您在代码中所指的实际上是构造函数。

于 2019-07-10T17:30:54.337 回答
0

Boss不引用类的实例,它将引用构造函数Boss,它只是整个代码中的一个。在方法中,您不是向实例添加属性,而是向构造函数添加属性。

您需要使用this对象的方法来访问实例内部。

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

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


let boss = new Boss();
boss.name = 'Bob';
boss.age = 55;

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


console.log(boss2.name);

console.log(boss.name);

于 2019-07-10T15:44:07.560 回答