[[Class]] Property of Host Object
dhtmlkitchen at gmail.com
Sat Jul 17 00:37:49 PDT 2010
On 7/16/10, Mark S. Miller <erights at google.com> wrote:
> On Fri, Jul 16, 2010 at 9:54 PM, Garrett Smith
> <dhtmlkitchen at gmail.com>wrote:
>> I have a question reqarding [[Class]] property as defined In ES5:
>> | The value of the [[Class]] internal property of a host object
>> | may be any String value except one of "Arguments", "Array",
>> | "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number",
>> | "Object", "RegExp", and "String"
>> May it be something other than a string value? Or must it be a string
> It must be a string value.
The specification says "may".
>> Why must a host object's class be none of the built-in classes listed?
> So that the [[Class]] property serve as a reliable nominal type check for
> the contract that the other internal properties and methods satisfy. This is
> used primarily within the spec itself. Previously, it wasn't clear what was
> meant when the spec said, for example, "if F is a function". Now we clearly
> say "if the [[Class]] of F is 'Function' " if that's what we mean.
I think I see the problem.
What you really want to say there is:
| The value of the [[Class]] internal property of any non-native host
| object must be any String value except one of...
Because that allows `alert` to be any native ECMAScript object
(Function, Object, etc), while still letting it be defined as a host
object and not violating that spec. Iff, however, following my
proposed amendment, `alert` had [[Class]] "Object", and it was not a
native ES object (as in IE versions), then it would be a specification
> But it is also used from JS. Host objects are exempt from most of the
> specific behaviors specified for specific kinds of native objects. Were a
> host object to be able to allege to be a kind of native object without
> behaving as that kind of native object behaves, that would be bad.
This is not in the spec:
"without behaving as that kind of native object behaves"
While the specification does not preclude the possibility that a host
object may be implemented with native semantics, it nonetheless
defines a host object:
| host object
| object supplied by the host environment to complete the
| execution environment of ECMAScript.
| NOTE Any object that is not native is a host object.
And that means that `alert`, `window`, `document`, XMLHttpRequest, are
all host objects. Whether or not those objects are implemented as
native ECMAScript objects is another matter altogether.
It seems the the spec is wrong and that you have misinterpreted it. I
believe that instead it should be written:
>> Implementations don't agree; when calling `Object.prototype.toString`
>> with a host object, the result will often be one of those values.
>> results either "[object Function]" or "[object Object]". That behavior
>> is allowed in ES3, but why not in ES5? ES5 seems to defy what most (if
>> not all) implementations do there.
> As far as ES5 is concerned, an implementation is perfectly allowed to have
> alert's [[Class]] be "Function", iff alert on that platform is a function,
> i.e., behaves as a function is obligated to behave. In fact, I think that is
> the most reasonable choice. If alert on a given implementation is instead a
> host object, then it has almost no rules governing its behavior. We don't
> wish it to be able to claim otherwise.
> I have not yet seen any draft of the new WebIDL bindings for ES5. These may
> very well determine whether alert is a host object or a native function, as
> far as w3c specs are concerned. Either decision would be allowed by ES5.
>> Some host objects including `alert` are implemented as a native
>> ECMAScript objects (`alert instanceof Function`). In that case, the
>> [[Class]] property should be "Function".
> (alert instanceof Function) is not a reliable test in either direction.
No of course not.
> host object as well as a native non-function is perfectly free to inherit
> from Function.prototype and thus pass this test. And an actual function may
> be an instance of Function constructor from another frame and so fail the
> test. But yes, iff alert is indeed a native function, it's [[Class]] should
> be "Function".
Therein lies a contradiction: A host object here may be a function.
Yet because it is a host object, that same object's [[Class]] must not
be "Function", and yet again, since it is a function, and any function
must have [[Class]] "Function", then this object's [[Class]] must be
>> However according to ES5 specs, any host object must not be withing
> the set of values that are not allowable and so the assertion could be
>> made that if any object has a [[Class]] that is one of those values,
>> then the object is not a host object.
> Yes, that is intentional.
Then it will fail today, as
- will result "[object Object]" or "[object Function]"
> Surely you meant "_toString.call(m)"? And of the two names above, I think
> asHostObject is more appropriate, as it applies whether m is method-like or
> Other than those typos, this code looks fine. Once one has determined that
> the platform is ES5, I think this code is perfectly good to use.
No, definitely not. It is not interoperable. Results vary depending on
the browser and host object in question. It does not reliably indicate
if an object is a host object, and in fact, that is too generous,
because in none of the implementations I tested will it indicate that
`alert` is a host object, which it is.
>> However, we know that won't hold true in many cases more than just
> Any implementation in which this doesn't hold is not a conformant ES5
> implementation, and shouldn't claim otherwise.
All or most browser implementations will result either "Function" or
"Object" for [[Class]] property of `alert`, and so the above function
(typos fixed) would fail in every implementation.
It seems that the specification should change to reflect what
implementations do and what is wanted by other parts of the spec, as
More information about the es-discuss