如何使一个类的实例可比较并且可以同时进行垃圾回收?

时间:2019-02-02 11:46:18

标签: javascript performance

我正在编写class,并希望实例与<>==具有可比性。

对于<>valueOf可以正常工作。

==不同,但是我也希望如此。我可以很容易地实现isEqual方法,但这并不相同。

我当前的解决方案是对所有已创建对象的缓存:

const cache = {}

class Comparable {
  constructor (id) {
    if (cache[id]) return cache[id]

    cache[id] = this
  }
}

这样,比较就可以了。不幸的是,这也会阻塞垃圾收集器。

是否有另一种启用new Comparable(42) == new Comparable(42)的方式,而这并不妨碍GC?

2 个答案:

答案 0 :(得分:2)

您似乎正在寻找hash consing,但是由于您遇到的问题,由于JavaScript不(yet)不支持弱(或软)引用,因此无法有效实现。

否,无法覆盖JS中的任何运算符,包括====将始终通过引用比较两个对象,您对此无能为力。最好的选择是创建一个compare方法。

答案 1 :(得分:0)

首先要记住,==总是比===更糟糕,因为存在这样的麻烦。 当您使用x == y比较,其中两个操作数都是对象,然后将JS比较它们为对象。 (更这里https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) 只需运行即可轻松测试

class ComparableObject {
  constructor(id) {
    this.id = id;
  }

  valueOf() {
    console.log("log", this.id);
    return this.id;
  }
}

new ComparableObject("12") == new ComparableObject(12);

它不会产生任何日志,但是:

new ComparableObject("12") == new ComparableObject(12).valueOf();

将打印:

log 12
log 12
true

有您的需求,几个解决方案:

Number(new ComparableObject("12")) == Number(new ComparableObject(12));
new ComparableObject("12").valueOf() == new ComparableObject(12).valueOf();

在缓存对象不会删除对实例的引用之前,GC无法执行任何操作。