On Feb 9, 2009, at 6:29 PM, Waldemar Horwat wrote:

Brendan Eich wrote:
I’ve tried various formulation of a simple statement about host objects but I keep finding potential holes and coming back to the conclusion that the only meaningful thing to do is to explicitly enumerable the invariants associated with each predefined [[Class]] value. Does anybody have a simpler solution? Does anybody want to volunteer to identify the invariants?
I think Chapter 15 already does identify the invariants, but you're right that multiple globals are not specified. In a single-global embedding, I would want any host [[Class]] == "Array" impostor to create instances whose prototype was Array.prototype, though. Wouldn't you?

Not necessarily. Array.prototype could be further up the prototype chain, or perhaps they could share a common prototype that constitutes a more generic kind of arrayness than Array.

I'm against such ontological confusion :-P.

It's true that almost all Array methods are generic (toString isn't, as seen below), but the custom [[Put]] in ES1-3, now [[ThrowingPut]] in 3.1, would be on a prototype and so would not be called when indexed properties were assigned to the directly referenced array-like object:

js> a = []

js> o = {__proto__:a} // Object.create in ES3.1
Array.prototype.toString called on incompatible Object
js> o.toString = function()this.join(",")
function () this.join(",")
js> o

js> o[0]=0
0
js> o[1]=1
1
js> o

js> o.length
0
js> o[0]
0
js> o.hasOwnProperty(0)
true

A host object that has Array.prototype on its prototype chain could do more work by defining a [[ThrowingPut]] that maintains length, but the spec would have to say that such a [[ThrowingPut]] works exactly the same as the one spec'ed in 15.4.5.1.

Object.getPrototypeOf would disclose a difference in prototype relations from "real" Arrays too.

There are several notions of "array-like" or "arrayness", where an object:

* has a .length property whose uint32 value is one greater than the maximum uint32 conversion of any property name that converts back to the same string name.

* has a .length property that can be set to a lesser value than its current value to truncate or extend the set of indexed properties (not all would-be arraylikes can be truncated or extended in my experience).

* has the Array.prototype generic method suite, and possibly a toString that works the same as Array.prototype.toString.

* has Array.prototype on its prototype chain, either immediately or further up the [[Prototype]]-linked chain.

The meaning of [[Class]] == "Array" should include all of these, and I think Array.prototype should be the immediate prototype.

In implementations, [[Class]] corresponds to a native class (vtable) that implements [[ThrowingPut]], [[Prototype]], and other spec- internal properties. An implementation might be able to mix in different native classes but they would not be composed along the prototype chain. I'm not sure how the spec would even talk about such implementations, other than by doing what Allen said and requiring indistinguishability from native Array objects. Having Array.prototype as other than the immediate prototype breaks indistinguishability.

/be
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to