Design principles for extending ES object abstractions

Brendan Eich brendan at
Sun Jul 10 16:01:13 PDT 2011

On Jul 10, 2011, at 3:54 PM, Brendan Eich wrote:

> On Jul 10, 2011, at 3:02 PM, David Herman wrote:
>>>> I'm not sure what Array.prototype methods would or wouldn't work on instances of SubArray.
>>> All of them.  They are all generic.
>> We're speaking too broadly here. It depends on what we want to work how. For example, .map can't magically know how to produce a SubArray as its result if that's how SubArray wants it to work.

This is the real concern, I believe. The Array methods (all generic in that they take array-like |this| -- at least one is Array-specific in argument handling: concat) that return a new array always make an instance of Array.

Alex Russell brought up the idea of extending these array-producing methods to call a user-defined constructor. We discussed doing it by reflecting on this.constructor, but that is not a compatible change: people today call intending to get an Array instance whose elements come from the arguments object. It would be wrong to change this code to return a new Object, but that's what reflecting on this.constructor would do, because:

js> function f(){return arguments.constructor}
js> f()
function Object() {[native code]}

So we have two choices:

1. Duplicate the array methods with new twins mutated to reflect on this.constructor -- this is ugly and bloaty, even if we can segregate the methods so as to avoid mangling the twins' names.

2. Add a new protocol, perhaps enabled by setting a well-known private name object (i.e., a unique public name), denoted it kResultConstructor, so that the methods can detect something like this[kResultConstructor].

(2) adds a bit of runtime cost to the methods, which are not super-optimized in many way in today's engines. Not sure that hurts it much, compared to (1). Do modules help us make a better, less bloaty form of (1)?


More information about the es-discuss mailing list