在《 Eloquent JavaScript》一书中,它要求创建一个PGroup类,该类与上一个练习中创建的类相似。它基本上就像一个简化的Set类,具有添加,删除和具有方法。我完全不了解的特定部分在最后。它说:


  “尽管构造函数不应该是类接口的一部分(尽管
  您肯定会在内部使用它)。相反,有一个
  空实例PGroup.empty,可以用作起始值。
  为什么只需要一个Pgroup.empty值,而不是一个
  每次创建一个新的空地图的功能?”


这是该问题的给定答案:

class PGroup {
  constructor(members) {
    this.members = members;
  }

  add(value) {
    if (this.has(value)) return this;
    return new PGroup(this.members.concat([value]));
  }

  delete(value) {
    if (!this.has(value)) return this;
    return new PGroup(this.members.filter(m => m !== value));
  }

  has(value) {
    return this.members.includes(value);
  }
}

PGroup.empty = new PGroup([]);

let a = PGroup.empty.add("a");
let ab = a.add("b");
let b = ab.delete("a");


tldr:什么是PGroup.empty?

编辑:为了消除混乱,我的意思是我不了解PGroup.empty的目的,甚至与类PGroup有关。例如,它是否是构造函数的属性?

最佳答案

PGroup.empty代表一个空集。您可以使用PGroup.empty作为创建更多集合的起点。

使PGroup的这种特殊实现有趣的是,adddelete方法不会修改您正在操作的现有PGroup实例。相反,adddelete返回全新的PGroup实例。这意味着,每次在已有的PGroup中添加或删除元素时,都将创建一个全新的PGroup实例,而不是修改现有的PGroup实例。

使用此模式意味着给定一个空集(在我们的示例中为PGroup.empty),我们可以创建一大堆其他PGroup,而无需显式使用new关键字。特别是,如果我们想要一组['a', 'b', 'c'],则可以执行以下操作:

let abc = PGroup.empty.add('a').add('b').add('c');


而且,由于PGroup.empty实例本身在您调用add方法时不会更改,因此可以多次使用相同的PGroup.empty实例。

let xyz = PGroup.empty.add('x').add('y').add('z');
let efg = PGroup.empty.add('e').add('f').add('g');


不变性的这一方面使我们能够满足以下要求:


  构造函数不应该是类接口的一部分


相反,我们可以使用adddelete创建更多的PGroup实例。

使adddelete创建PGroup的新实例而不是修改PGroup的现有实例的技术术语称为immutibility

09-25 21:32