Making "super" work outside a literal?

Sean Eagan seaneagan1 at gmail.com
Fri Jun 24 06:57:28 PDT 2011


On Fri, Jun 24, 2011 at 5:08 AM, Allen Wirfs-Brock
<allen at wirfs-brock.com> wrote:

> I agree that  the Object.defineProperty should apply defineMethod semantics when processing a "get" or "set" attributed as these are essentially method definition operations.
> I don't think it should do so for "value".

I think it is inconsistent to update |super| for "get" and "set", but
not for "value".

> It is possible that a data property is being used as a function valued data store rather than as a method binding on an object. For example, a property might be used to store a callback function.  Such a data-value function might reference |super|.  For example, it might be a function with a bound |this| that also uses |super|.  I don't thing we want the |super| binding changing in such situations.  (Looking at this another way, if such a transformation of done in Object.defineProperty and not in [[DefineOwnProperty]] then there would be a semantic difference between obj.prop=func and Object.defineProperty(obj,"prop",{value:func}) that we probably don't want to have.)
>
> I introduced the concept of defineMethod to define a means to explicitly disambiguate  the attachment of a method and the setting of a data property value in situations where it makes a difference.  People will run into bugs where they used = or defineProperty with the value attribute when they really need to do a defineMethod but at least with defineMethod there is a way to fix this bug.

I agree, this is why I proposed the Object.defineSuperProperty
solution, as an explicit means to update |super|.  It is like
Object.defineMethod except that it allows you to use the
"configurable", "writable", and "enumerable" attributes with methods,
and is also an explicit means to update |super| for accessor getters
and setters.

Object.defineSuperProperty also avoids a proxy trap because it can
essentially have the same semantics as Object.defineProperty except
that it creates functions with updated [[Super]] before passing the
property descriptor to [[DefineOwnProperty]] where the
"defineProperty" trap will be called.

Probably Object.defineSuperUsingProperty would be more accurate name.

Another option would be to add a boolean "updateSuper" argument to
Object.defineProperty.

Another option would be an |Object.updateSuper(object, "foo")| which
assigns functions with updated |super| to any "value", "get", and
"set" attributes which contain functions which use |super| of an
existing property, calling [[DefineOwnProperty]] with the new values.

>>> Also, I wonder if there is a need for a Function.prototype.isSuper
>>> similar to Function.prototype.isGenerator?
>>
>> A generator is a kind of function. 'super' evaluates to an object. So this seems misplaced, but first, what use-case does it serve? Can you show an example that motivates it?
>
> I think both of these fall into the realm of reflection.  As such, I would want to keep them off the instances. If we need them I would make them:
>  Function.isGenerator(func)

I think Function.prototype.isGenerator appears to already be
harmonized, so that should probably be discussed further then.

>  Function.usesSuper(func)

Yeah, that would probably be a better spot for it.

> however, WRT usesSuper, I isn't clear if it is anymore necessary than usesThis, hasNestedFunctions, hasIfStatements, and potentially hundreds of reflective queries that might be made about a function.

It could be used to determine if you need to do an
Object.defineSuperUsingProperty / Object.updateSuper /
Object.defineMethod or whatever we land on.

Cheers,
Sean Eagan


More information about the es-discuss mailing list