What prevents built-in constructors from being extended?

Lasse Reichstein reichsteinatwork at gmail.com
Mon Dec 5 10:35:30 PST 2011


On Sat, Dec 3, 2011 at 8:27 AM, Axel Rauschmayer <axel at rauschma.de> wrote:
> I’m still trying to understand why some of the built-in constructors can’t be extended. The following describes my current understanding. If you would, please let me know where/if I’m wrong.
>
> - The following built-in constructors can’t be easily extended:
>    Array
>    Boolean
>    Date
>    Function
>    Number
>    Object
>    RegExp
>    String
>    Error and sub-constructors
>
> - Reason (Array): Array instances need special support to update the length property depending on what elements are added. But that specialness should go away with Allen’s proposal for overriding element access via [].

Arrays have a special [[Put]], but Strings have a special [[Get]] too,
so Array isn't the only one with a custom internal method.

> - Reason (all): The constructors can’t be invoked as functions while handing in `this` – be it that they create new instances, be it that they do something else – they can’t be made to add properties to an existing instance. This prevents the pattern SuperConstructor.call(this, arg1, arg2, ...) from working.

That would be messy.
If the String constructor could add "String-ness" to an existing
object, what would it do to a Number object (which already have a
[[PrimitiveValue]] property), or an Array (which might already have a
"0" property), or a something that's already a String object, or ...
the possibilities are staggering :) Would it change the [[Class]] of
the obejct?
It's going to be hard to make that safe.


What you need (if you need it) is a way to create a, say, Date object
with a custom [[Prototype]].
That's why the common example given is Array.create - working
similarly to Object.create, but creating Array objects (with class
"Array" and Array behavior), just like Object.create creates Object
objects. Ofcourse this needs a .create on all the special
constructors.

Another option is to make a more generalized
Object.createByClass("Array", proto) that creates an object with class
"Array" and, since "Array" is a known class, also adds Array nature to
the created object. Doing Object.createByClass("arglebargle",
Object.prototype) just gets you an object where
Object.prototype.toString returns "[object arglebargle]'.

/L


More information about the es-discuss mailing list