*Chrome console:*
let a = Object.create(Set.prototype);
a instanceof Set // true
a.add(1); // Uncaught TypeError: Method Set.prototype.add called on incompatible receiver #<Set>
Set.prototype.add.call(a); // the same as above
This is really confusing.
In short: you can't do this because the specification says you can't.
See step 3 of Set.prototype.add:
If S does not have a [[SetData]] internal slot, throw a TypeError exception.
The reason for this restriction is that the Set
methods require certain internal state in the object they are operating on. Having the right prototype is not enough; you must also call the Set
constructor for your objects, which will create those internal fields.
I guess what you're trying to do is to subclass the built-in Set
. As the spec also points out, that is easily possible using ES6 class syntax:
class MySet extends Set {}
var s = new MySet();
s.add(1);
See also this question: Inheriting from Set.prototype.