W3C home > Mailing lists > Public > public-script-coord@w3.org > October to December 2011

[Bug 14877] Define [[Class]] of interface prototype objects, exception interface objects, and exception interface prototype objects

From: <bugzilla@jessica.w3.org>
Date: Thu, 15 Dec 2011 20:55:31 +0000
To: public-script-coord@w3.org
Message-Id: <E1RbIKx-00051o-HC@jessica.w3.org>
https://www.w3.org/Bugs/Public/show_bug.cgi?id=14877

Travis Leithead [MSFT] <travil@microsoft.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |travil@microsoft.com

--- Comment #22 from Travis Leithead [MSFT] <travil@microsoft.com> 2011-12-15 20:55:28 UTC ---
(In reply to comment #17)
> That's a really good point, and now that you point it out, I agree.  For
> consistency with ES, we should define the [[Class]] of an interface prototype
> object to be the identifier of the interface, and the [[Class]] of an exception
> interface prototype object to be the identifier of the exception.  The
> [[Class]] of interface objects and exception interface objects should remain
> "Function", as now.  (I was confused in comment 9 when I talked about the
> [[Class]] of exception interface objects not being defined -- it clearly is.)

Makes sense to me, and is the most aligned with ECMAScript.

Note that the [object Function] ambiguity is a side-effect of switching
everything over to be a function instance. We should either accept the
consequence of this change, or go back to interface objects as instances of
Object (and new-able constructors as Function instances)--which I wouldn't mind
a bit, since that what IE9 does today; however that re-opens a closed issue.


(In reply to comment #21)
> I agree with Aryeh that choosing ({}).toString.call(Node.prototype) == "[object
> Node]" is best, since that allows for the debugging that Travis wants as well
> as being consistent with ES builtins as Garrett points out.

Why not "[object NodePrototype]" since that has the most interop according to
your results? It also allows differentiation between String(Node) and
String(Node.prototype) which given your proposals are indistinguishable?

> Do people think there's much advantage to having String(Node) == "function
> Node() { ... }", now that interface objects are function objects?  It would be
> consistent with the builtin constructors like Object, String, etc.  OTOH 
> "[object Node]" is a slight winner from the results.

Having String(Node) return "function Node() { ... }" is the default ECMAScript
behavior when passing any function instance into the String constructor:

function foo() { }
String(foo) == "function foo() {}"

I don't think we should change that.

> For (2), (4) and (6), we'd need to have toString functions on interface 
> objects to override the one from Function.prototype.

This would really be a waste for IE, because it would add a signficant start-up
performance cost to our engine for every web page load (doubling the cost to
init every interface object into the script engine due to the extra method).
I'd have a hard time convincing our perf-concious developers to make this
change only for the debugging value; furthermore, the unique-named value is
already provided by the String() behavior as noted (without additional changes)
and works for the majority of APIs that perform object/function-to-string
coercion like console.log/alert/etc.

Your comparisons use Node but that's not [currently] represented as a function
instance in IE, so to make a more apples-to-apples comparison of browsers, I
make sure that the reported object types are the same via typeof. XHR worked
best for this:

name="XMLHttpRequest"

Browser typeof(name) {}.toString.call(name)   String(name)
======= ==========   ======================   ============
Fx      function     [object DOMConstructor]  [object XMLHttpRequest]
Cr      function     [object Function]        function XMLHttpRequest() {..}
Sa      object*      n/a                      n/a
Op      function     [object XMLHttpRequest]  function XMLHttpRequest() {..}
IE      function     [object Function]        function XMLHttpRequest() {..}

(I couldn't find any interface or prototype DOM objects in Safari that reported
as function for typeof in my quick tests, therefore their results aren't
comperable in this table).

There's pretty good consistency for the String() behavior of interface objects
that are functions.

Firefox seems to be contradicting itself by reporting typeof "function" but
stringifying as "[object ...]".

Comparing these browser's behavior against native ECMAScript functions, where
function Foo() { } is created before running the tests shows good alignment for
all and [I think] sets a baseline:

name="Foo"

Browser typeof(name) {}.toString.call(name)   String(name)
======= ==========   ======================   ============
Fx      function     [object Function]        function Foo() {}
Cr      function     [object Function]        function Foo(){}
Sa      function     [object Function]        function Foo() { }
Op      function     [object Function]        function Foo() { }
IE      function     [object Function]        function Foo() {}

It looks to me like Chrome and IE (from the first table) have the closest
behvior to ECMAScript handling of function interface objects.

And finally, comparing the results of an interface Operation (getElementById)
and how it behaves under the same conditions (becuase why have different
behavior if we're talking about function instances?)

name="document.getElementById"

Browser typeof(name) {}.toString.call(name)   String(name)
======= ==========   ======================   ============
Fx      function     [object Function]        function getElementById() {..}
Cr      function     [object Function]        function getElementById() {..}
Sa      function     [object Function]        function getElementById() {..}
Op      function     [object Function]        function getElementById() {..}
IE      function     [object Function]        function getElementById() {..}

Wow. Not bad. Someday we'll get there for interface objects and prototypes too
:)

I think that also sets a pretty consistent baseline.

So, here's my counter-proposal. We expect {}.toString.call() and String() to
behave as follows:

1. ({}).toString.call(Node)           == "[object Function]"
2. String(Node)                       == "function Node() { [native code] }"
3. ({}).toString.call(Node.prototype) == "[object NodePrototype]"
4. String(Node.prototype)             == "[object NodePrototype]"
5. ({}).toString.call(Image)          == (same as Node)
6. String(Image)                      == (same as Node)

-- 
Configure bugmail: https://www.w3.org/Bugs/Public/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
Received on Thursday, 15 December 2011 20:57:34 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 8 May 2013 19:30:05 UTC