Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is "Object"?)

Allen Wirfs-Brock allen at wirfs-brock.com
Sun Sep 30 10:46:46 PDT 2012


On Sep 29, 2012, at 11:11 PM, Brendan Eich wrote:

> Mark S. Miller wrote:
>> On Sat, Sep 29, 2012 at 10:21 PM, Mark S. Miller <erights at google.com <mailto:erights at google.com>> wrote:
>> 
>> 
>>    I agree that the only security issue is avoiding the
>>    communications channel.
>> 
>>    Security aside, given maximin
>> 
>>        class Foo
>> 
>>    what do you suggest Foo.prototype be?
>> 
>> 
>> That was too vague. Reformulating.
>> 
>> Private properties, i.e., properties named by symbols, are the class analog to the internal properties of the built ins. The current [[Class]] tests in ES5 are there essentially to ensure that these internal properties exist and satisfy whatever invariant is assumed. In maximin classes, we don't expand methods with an analog of that [[Class]] check. Rather, the presence of these private symbol-named properties implicitly provides the branding. Say class Foo uses symbol @s to name a private instance property of instances of Foo, and that method bar() of Foo accesses this @s property, failing if the object doesn't have an @s. Clearly, bar() should fail on Foo.prototype just as it should fail on any non-instance of Foo. This is already implied by the mechanisms proposed for installing private instance variables.
> 
> Yup, and I dig it (Jason Orendorff many years ago suggested that Date should not have a [[Class]] check, rather simply use private-named properties which might even be inherited).
> 

Just so everybody is on the same page here, "@@bar"  is an internal convention I'm experimenting with in the spec. draft for referring to Symbol values that defined in the specification and known to implementation.  So, @@toStringTag is a reference to a symbol that user code would generally reference as @toStringTag.  This symbol is used as a property key whose value is used to supply the "<tag> value" that Object.prototype.toString inserts into: "[Object <tag>]".  See 15.2.4.2 in the lasted spec. draft.  The @@toStringTag property is kind of like the internal [[Class]] property in that it is used to parameterize the output of Object.prototype.toString.  It is different in that it is can be supplied by user code for the objects they define.  It is different in that its value is not guaranteed to be unique or non-forgegable. You can't use Object.prototype.toString as a reliable nominal type tag for new built-ins or user defined objects.  Instead use a closely head private symbol.  The proposed definition of Object.prototype.toString preserves the ability to use it to do nominal type testing of the ES<=5.1 built-ins so existing code should work, as is. 

> So is the only issue here that @@toStringTag is not set to "Foo", as Yusuke just suggested?

As currently specified, class definitions do not  automatically define a @@toStringTag property on the prototype object.   It is up to the developer of a class to decide to provide it.  If none is provided it is obtain by inheritance up the prototype chain and would typically have the value "Object".  Note that not all class definitions include an identifier binding that names the class.  

Allen


More information about the es-discuss mailing list