skip to Main Content

The following doesn’t work:

const x = Object.create(Set.prototype)
x.has(1) // crashes with  Method Set.prototype.has called on incompatible receiver #<Set>
const y = Object.create(Map.prototype)
y.get(1) // crashes with  Method Set.prototype.has called on incompatible receiver #<Map>

I was hoping for a type-independent way of creating empty objects.
Why doesn’t the above work like that?

2

Answers


  1. Chosen as BEST ANSWER

    A better way to do it:

    call new ctor where ctor is the object's contructor.


  2. Object.create creates a new ordinary object inheriting from the passed argument. It does nothing to initialise that object, like call the constructor.

    In the case of Set and Map, calling the constructor essential, as that creates the internal slots which the collection needs to function (in particular, to store elements). These internal slots must be constructed together with the object, they cannot be added afterwards. This works only by calling the constructor with the new keyword.

    When you use Object.create, the objects inherit has and get methods from the respective prototype object just fine, but when calling them their receiver (this value) is the ordinary object which is missing those internal slots that would make it a true Set or Map, and the methods throw an exception.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search