Does the ECMAScript specification allow Array to be “superclassable”?

前端 未结 2 948
萌比男神i
萌比男神i 2021-02-13 03:59

I\'m looking for any indications whether or not "superclassing" a builtin type will work according to the specification. That is, given any hypothetical confo

相关标签:
2条回答
  • 2021-02-13 04:54

    Calling your setSuperclassOf function on any ECMAScript builtin class will not affect the behaviour of the constructor.

    Your HypotheticalArray constructor should not - must not - call super(). In the spec, you should not just look at the The Array Constructor section which gives a short overview, but also at the subsections §22.1.1.1 Array(), §22.1.1.2 Array(len) and §22.1.1.3 Array(...items) which give the detailed algorithms of what happens when you call Array (as either a function or constructor). They do look up the prototype of the newTarget (to be subclassable as usual - since ES6), but they do not look up the prototype of the Array function itself. Instead, they all do directly dispatch to the ArrayCreate algorithm, which just creates an object, sets up its prototype and installs the exotic property semantics.

    It's similar for String (which dispatches to the StringCreate algorithm when called as a constructor), the abstract TypedArray constructor (which just throws and explicitly states that "The TypedArray constructors do not perform a super call to it."), the concrete TypedArray constructors (which dispatch to the AllocateTypedArray and IntegerIndexedObjectCreate algorithms), and the Map and Set constructors (which both dispatch to the OrdinaryCreateFromConstructor and ObjectCreate algorithms). And afaik it's the same for all other builtin constructors as well, though I haven't checked each of them individually, there are just too many as of ES8.

    My understanding is that because Array.prototype itself is an Array exotic object, a compliant implementation is not required to internally call super() within the Array constructor in order to properly initialize the instance as an array exotic

    No, that has nothing to do with it. An object doesn't become exotic because it inherits from an exotic object. An object is exotic because it was specifically created as such. The value of Array.prototype can be really anything, it's not relevant for the creation of array instances - apart from that it'll be used as the prototype when new Array is called (in contrast to new ArraySubclass).

    Regarding Object.setPrototypeOf(Array.prototype, …), notice that Array.prototype is not even an immutable prototype exotic object like Object.prototype, so yes you are allowed to do that.

    0 讨论(0)
  • 2021-02-13 04:57

    Based on the guarantee outlined in §9.3.3 CreateBuiltinFunction ( steps, internalSlotsList [ , realm [ , prototype ] ] ) and the steps in §22.1.1 The Array Constructor, no possible invocation of Array(…) or new Array(…) will call the Object constructor, or the constructor of Array's resolved super class at the time of invocation, and therefore "superclassing" Array is guaranteed to behave properly in any conformant implementation of ECMAScript 2018.

    Due to the discovery of §9.3.3, I suspect the same conclusion will be drawn for the remaining classes in the current specification, though there is a lot more research required to determine whether this is accurate, and guaranteed back to ECMAScript 2015.

    This is not a full answer, and therefore I will not be accepting it. A bounty will still be rewarded to a full answer, regardless of whether or not it is provided before my question is eligible for bounty.

    0 讨论(0)
提交回复
热议问题