Array Like Interface

Garrett Smith dhtmlkitchen at gmail.com
Thu May 14 17:59:18 PDT 2009


One statement that comes up a lot on comp.lang.javascript is "don't
trust host objects". There cases where [[ToBoolean]], [[Put]], and
[[Get]] throws in IE, but also in Firefox where the property is
implemented as a getter, with no setter.

The implementation is responsible for ensuring the successful outcome
of performing an Array operation on a Host object. A common interface
for Array generics define an expected behavior, making the outcome of
array generic operations on Host objects more clearly defined (and
hopefully more reliable).

An example of where it might be useful to use Array Generics on a host object:-

var items = list.getElementsByTagName("li");
items = Array.slice(hostObj);

Results in Error in IE. Too bad, because it would be really useful to
sort, filter, map, or reverse those items.

It isn't a bug of IE, even though it might seem to be. The problem is
that the operation may legally fail. ECMAScript 5 draft states:-

| Whether the slice function can be applied successfully
| to a host object is implementation-dependent.

This seems to go against the nature of Section 4 of ES5 which states
that host objects "provide certain properties that can be accessed and
certain functions that can be called from an ECMAScript program."

Could it ECMAScript 5 further state:-
"A host object may also implement interfaces that are compatible with
interfaces defined herein."

Could ECMAScript 5 make it easier for the Host environment to define
such interface?

- and then go on to define a List interface (below), which has only
the length, and [[Put]] and [[Get]] methods, but none of the
Array.prototype methods?

I'm envisioning a scenario where ECMA defines a common interface for a
"List" and a common Host array-like collection Interface that is
predictably compatible.

In ECMA land, methods that take Array-like methods ("List") could make
the outcome of attempts of using array-like Host objects more
predictable (so one would know what would happen before calling
slice.call(hostListObj)). Such interfaces would exist in ECMAScript
and in any Host environment. It would be defined in a way that was
simple, and clearly and predictably compatible (or incompatible). Such
Interface doesn't exist yet.

In Host land, Array-like collections in browsers could include
NodeList, StyleSheetList, CSSRuleList. The Host environment would have
to define a separate interface for these guys, so NodeList and the
others would extend (or implement) the Array-like "List."
Implementations could  implement this interface for their own
interfaces that may be nonstandard, such as window.frames[1] (if that
has not made it into Ian Hickson's HTML 5 yet).

This change to Host objects would not constrain or restrict the Host
objects, but would instead define a smaller subset of collection-like
behavior.

To define Interfaces that could be used for Array Like collection for
Host objects (in web pages):-

List {
  attribute unsigned long length;
  [[Get]]
  [[Put]]
}

and

UnmodifiableList extends List {
  [[Put]] raises exception / [[ThrowingPut]] in ECMA
}

If ECMAScript Array were to implement a List interface and Web IDL[2]
were to define a compatible interface, the Array generics could be
expected to work on instances of the respective interfaces, provided
the ability to determine if, in fact, the object in question
implements that interface. Surely, it would be very nice to also have
a built-in method by which to determine this, so that Host objects
could then implement this behavior, and be tagged. For example:-

if(List.isList( unknownObject )) {

}

That way, you could use a Host object "List" instance as the thisArg
to an ECMAScript method that expects an ECMAScript List instance which
defines behavior on an ECMAScript "List" and (provided the interfaces
were compatible) get an expected outcome.

ECMAScript should should define an array-like object Interface in one
place. It should define a common Interface for Array.prototype, so
that Array.prototype would fulfill that interface, and that any Host
object that also wants to fulfill that interface can, too, and still
be a Host object, not an Array. This change would not affect the
behavior of current implementations; it would merely change the
interface so that other specs for Host objects could define a
compatible interface.

Garrett

[1]https://developer.mozilla.org/En/DOM:window.frames
[2]http://dev.w3.org/2006/webapi/WebIDL/#indexed-property-xattrs


More information about the es-discuss mailing list