Skip to content

Removing observable lookup/call of %SetPrototype%.add in new Set #1430

Open
@bakkot

Description

@bakkot

The Set constructor when called with an iterable behaves as follows:

  1. Create a new object with the appropriate prototypes derived from NewTarget
  2. Look up add on that object
  3. Repeatedly invoke add on the new object passing each member of the iterable

I believe the lookup for add is to support subclasses overriding add, such that

class A extends Set {
  add(x) {
    console.log(x);
  }
}
new A([0, 1]);

But this also has the consequence that changing Set.prototype.add changes the behavior of the Set constructor, which adds implementation overhead. I don't think it's intended or necessary that Set.prototype.add be monkey-patchable in this way. Perhaps we could say that if NewTarget is the Set constructor itself (edit: from the same realm), it can just use the original Set.prototype.add. This would preserve the subclassing behavior (i.e., my example would work the same) while reducing complexity in the common non-subclassed case.

This would debatably be an inconsistency, but it's only observable if you're patching intrinsics, which is a case where I don't think we should worry too much about trying to maintain consistency.

This all applies to WeakSet, Map, and WeakMap as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs consensusThis needs committee consensus before it can be eligible to be merged.normative changeAffects behavior required to correctly evaluate some ECMAScript source textquestion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions