- From: Jonas Sicking <jonas@sicking.cc>
- Date: Fri, 11 Nov 2011 01:05:11 -0800
- To: Webapps WG <public-webapps@w3.org>, public-script-coord@w3.org
Hi All, So, we've debated a lot the exact syntax for .find/.findAll. However I intentionally requested that we split out the discussions about return type for .findAll to a separate thread. So I'm starting that thread here. There are a few goals for the return'ed object that I've envisioned based on discussions so far: 1. It should have at least all of the non-mutating Array methods on it. Possibly the mutating methods too if we allow the returned object to be mutable. 2. It should have a object on the prototype chain where we can insert functions that are specifically useful for lists of nodes. Examples include .find/.findAll/.matchesSelector/.remove/.addEventListener 3. It would be good if it had the Array prototype object on it's prototype chain so that if Array.prototype was extended, it would affect this object too. 4. The object will *not* be live since live results from selector matching is slow. Since the returned object won't be live, I don't see a reason to make it immutable. Hence it seems like we could put Array.prototype on the prototype chain which would immediately make all non-mutating as well as mutating functions available on the object. We should also insert a new prototype object in the prototype chain. Hence we end up with something like: object -> [some type].prototype -> Array.prototype -> Object.prototype. And to ensure that the object acts as much as possible as an array it should also have it's [[Class]] set to that of an array. This has subtle effects on a number of functions. For example it affects what Object.toString() and Array.isArray returns, it affects how Array.concat behaves, and it affects the JSON serializer. I'm not sure if setting the [[Class]] to that of an array also gives the object the magical .length property, but if it doesn't, we need to also define that the returned object has such a property. Note that for Arrays, .length doesn't live on the prototype chain, but is rather a special property on the object itself. In other words, the returned object is exactly what you'd get if you did: a = new Array; a.__proto__ = [some type].prototype; [some type].prototype.__proto__ = Array.prototype; and then filled a with the set of nodes which matched the selector passed to .findAll. So the remaining question is, what should we use for [some type]. One option is to use NodeList. However this would result in NodeLists having Array.prototype on it's prototype chain. Including all mutating functions. This is iffy in general since NodeLists are returned from several APIs which return objects which represent a live result of a query. For example .getElementsByTagName, .getElementsByClassName and .childNodes. An additional source of iffiness with this idea is that several of the mutating methods on Array.prototype don't throw if called on a immutable objects. For example .pop, .shift, .sort and .reverse all would not throw if called on an empty immutable list. Hence I propose that we add a new type. I don't care much for naming things so I'll just suggest NodeArray for now and let others fight it out over the name. For now we can leave NodeArray as empty and just let it be an extension point for page authors. We can discuss separately if .findAll/.matchesSelector should be added to NodeArray, and if so how they should behave. However, we should probably use NodeArray to "fix" one of the problems with some of the functions on Array.prototype. For example Array.prototype.filter always returns a new Array object. This would mean that: elem.findAll(...).filter(function(node) { ... }); will return a plain Array and not a NodeArray. However we could make NodeArray override all such functions and keep their behavior identical except that they return NodeArrays. Another way to fix this problem would be to change the definition of Array.prototype.filter, but I have no idea if that's doable, or how that would be done. What do people think? / Jonas
Received on Friday, 11 November 2011 09:06:12 UTC