javascript collections

W

William Gill

I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array. I am
having great difficulty finding any good, comprehensive documentation on
javascript collections and their methods. Can anyone point me to a good
reference?

While we are on the subject of references I'm open to suggestions in
general. I prefer to have down-loadable, searchable references because
I hop back and forth between many, and the differences sometimes blur. I
frequently have trouble remembering language specific semantics and
terminology, (i.e. I may remember that something exists, and what it
is/does, but can't remember what it's called in that particular
language.) but I can usually search and find things that remind me of
what I'm looking for, and where to look for it.

Thanks.
 
G

Gregor Kofler

Am 2010-07-04 18:42, William Gill meinte:
I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array.

You are looking for a NodeList.
I am having
great difficulty finding any good, comprehensive documentation on
javascript collections and their methods. Can anyone point me to a good
reference?

There are not too many properties or methods.

For a start:
https://developer.mozilla.org/En/DOM/NodeList

Gregor
 
N

nick

I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array.  I am
having great difficulty finding any good, comprehensive documentation on
javascript collections and their methods. Can anyone point me to a good
reference?

What makes you call it a "collection?" Are you just using that as a
generic term for things that are like arrays but are not really
arrays? I tend to do that also; afaik "collection" has no predefined
meaning in js/es, so it seems safe to use as a generic word for things
like that... but because it's just a generic word, you won't find any
references on "collection" as if it were a real 'datatype' (ctor
function).

Chrome calls it a NodeList, as Gregor mentioned. Firefox doesn't seem
to have a special name for it, unless I've totally forgotten how to
use firebug since switching to chrome.

Check this out, it might be useful to you. Try putting it into the
chrome console one statement at a time. It'll work in ff/firebug too,
although the console.log lines seem pretty useless there.

// get a collection of nodes
var foo = document.getElementsByTagName('div');

// what kind of object is "foo?"
console.log(foo.constructor.prototype);

// --console output from previous line--
//
// Object
// constructor: function NodeList() { [native code] }
// item: function item() { [native code] }
// __proto__: Object

// so it's a NodeList. Looks like NodeList has a method named
// "item," but not much else.

// ...so maybe we'd be better off with an Array; it can do a lot
// more than a NodeList... Here's a trick (it's been discussed
// here before) to turn a array-like object into a true array.

foo = [].slice.call(foo);

// did it work?

console.log(foo.constructor.prototype);
// (shows prototype for Array ctor)

// let's see if we can use Array methods on "foo" now.

foo.reduce(function(p, n){
return (p.innerHTML || p) + n.innerHTML
}, '');
While we are on the subject of references I'm open to suggestions in
general.  

I like developer.mozilla.org, pretty thorough and straightforward,
good about pointing out deviations from standard. In general it seems
like most of the docs at moz pertain to most of the modern non-IE
browsers, but not so much IE, so it can be good to compare moz docs to
the docs on MSDN whenever you get around to hacking in IE support. ;)
I prefer to have down-loadable, searchable references because
I hop back and forth between many, and the differences sometimes blur.

Downloadable and searchable? You probably want those ECMAScript pdfs.
I'm sure someone here has a link. Those seem to be more targeted at
browser vendors than javascript programmers, though, so they can be
quite verbose. Also wget and grep are your friends.
I frequently have trouble remembering language specific semantics and
terminology, (i.e. I may remember that something exists, and what it
is/does, but can't remember what it's called in that particular
language.) but I can usually search and find things that remind me of
what I'm looking for, and where to look for it.

You could check out visibone's cheat sheets at www.visibone.com/javascript

I haven't recommended these in years because I don't use them myself
(I've seen them in print, though, they're good) but it sounds like the
kind of quick reference you might be looking for.
 
R

RobG

Am 2010-07-04 18:42, William Gill meinte:


You are looking for a NodeList.

No, a collection.
There are not too many properties or methods.

For a start:https://developer.mozilla.org/En/DOM/NodeList

The definitive reference is the W3C DOM Core spec, the above page has
a link to the DOM 3 Core reference, which doesn't seem to have changed
since Level 1.

However, the OP was asking about collections, which are a type of
NodeList that have some extra features:

DOM 2 HTMLCollection
<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506 >

DOM 2 introduced the HTMLOptionsCollection interface, which is similar
to other collections but differs in that the namedItem method accepts
only an id and that length is not readonly, so it can be used to set
the number of items (e.g. as a quick way to remove all options, set
length to zero):

DOM 2 HTMLOptionsCollection
<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#HTMLOptionsCollection
The relevant HTML5 reference is:
<URL: http://www.w3.org/TR/html5/common-dom-interfaces.html#collections-0
So given the following:

Array.prototype.shift.call(aCollection);

If aCollection is not an options collection, an error should result
similar to:

"Setting a property that has only a getter"

If aCollection is an options collection, the last option will be
removed from the DOM. However, setting the length directly is likely
more efficient:

aCollection.length = aCollection.length - 1;

though shift will return the deleted option element, setting the
length won't, so:

var deletedOption = Array.prototype.shift.call(optCollection);

and

var optsLength = optCollection.length - 1
var deletedOption =
selectElement.removeChild(optCollection[optsLength]);

should be equivalent.
 
R

RobG

What makes you call it a "collection?"

Because in DOM 1 it was an HTML collection and in DOM 2 and HTML5 it
is an HTML options collection. See my earlier post.

Are you just using that as a
generic term for things that are like arrays but are not really
arrays? I tend to do that also; afaik "collection" has no predefined
meaning in js/es, so it seems safe to use as a generic word for things
like that... but because it's just a generic word, you won't find any
references on "collection" as if it were a real 'datatype' (ctor
function).

Chrome calls it a NodeList, as Gregor mentioned. Firefox doesn't seem
to have a special name for it, unless I've totally forgotten how to
use firebug since switching to chrome.

Check this out, it might be useful to you. Try putting it into the
chrome console one statement at a time. It'll work in ff/firebug too,
although the console.log lines seem pretty useless there.

  // get a collection of nodes
  var foo = document.getElementsByTagName('div');

That returns a NodeList, not a collection.

  // what kind of object is "foo?"
  console.log(foo.constructor.prototype);

Replacing console.log with alert in IE 6 returns "undefined".
  //  --console output from previous line--
  //
  //  Object
  //    constructor: function NodeList() { [native code] }
  //    item: function item() { [native code] }
  //    __proto__: Object

  // so it's a NodeList. Looks like NodeList has a method named
  // "item," but not much else.

Which is per the W3C specification. The above is an unreliable way of
determining that - browsers are notoriously bad at implementing the
finer points of specifications consistently. Try it in IE 6.

  // ...so maybe we'd be better off with an Array; it can do a lot
  // more than a NodeList... Here's a trick (it's been discussed
  // here before) to turn a array-like object into a true array.

  foo = [].slice.call(foo);

  // did it work?

Maybe - in Firefox, yes. IE 6, no. Any Array method that requires
setting length (e.g. shift) will fail as it will try to set length,
which is readonly.

[...]
Downloadable and searchable? You probably want those ECMAScript pdfs.
I'm sure someone here has a link.

There are links in the FAQ:

<URL: http://www.jibbering.com/faq/#onlineResources >
 
G

Garrett Smith

Because in DOM 1 it was an HTML collection and in DOM 2 and HTML5 it
is an HTML options collection. See my earlier post.

DOM 2 HTML defines HTMLOptionsCollection.

http://www.w3.org/TR/DOM-Level-2-HTML/html.html#HTMLOptionsCollection

Though stragely, there is no base Collection. It would be useful to have
such object, and to have it specified as a native ECMAScript object in
an ECMAScript way, so that it would be said to have [[Get]] and `length`.

Garrett
 
N

nick

I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array [...]
What makes you call it a "collection?"

Because in DOM 1 it was an HTML collection and in DOM 2 and HTML5 it
is an HTML options collection. See my earlier post.

Ah, good to know.

I don't really get the part about collections having a readonly length
and option collections not having a readonly length but throwing an
exception when messed with "if setting the length is not allowed by
the implementation." Does that mean it's readonly in ie6 and not in
everything else, or what?
That returns a NodeList, not a collection.

As I noted in the comment you snipped. You're right, though, I naively
assumed nodes were nodes and d.gebtn would give me the same type of
things as myform.myselect.options, but it seems node collections are
slightly beefed up versions of node lists.
Replacing console.log with alert in IE 6 returns "undefined".

I didn't really expect ie6 to be useful here. What else would that
show anyway? something like "[Object object]"?
  //  --console output from previous line--
  //
  //  Object
  //    constructor: function NodeList() { [native code] }
  //    item: function item() { [native code] }
  //    __proto__: Object
  // so it's a NodeList. Looks like NodeList has a method named
  // "item," but not much else.

Which is per the W3C specification.

Good to know.
The above is an unreliable way of
determining that - browsers are notoriously bad at implementing the
finer points of specifications consistently. Try it in IE 6.

I wasn't trying to determine whether chrome was doing things by
specification, I just wanted to quickly see what it called the
constructor and if it had any useful methods. Thanks for linking the
relevant docs though.
Try it in IE 6.

Maybe later... Don't have it handy.
  foo = [].slice.call(foo);
  // did it work?

Maybe - in Firefox, yes. IE 6, no. Any Array method that requires
setting length (e.g. shift) will fail as it will try to set length,
which is readonly.

foo=[].slice.call(foo) doesn't change the length of the collection or
nodelist, so the resulting array 'foo' should have all Array.prototype
properties including a mutable length property. Or am I missing
something?

-- Nick
 
R

RobG

I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array [...]
What makes you call it a "collection?"
Because in DOM 1 it was an HTML collection and in DOM 2 and HTML5 it
is an HTML options collection. See my earlier post.

Ah, good to know.

I don't really get the part about collections having a readonly length
and option collections not having a readonly length but throwing an
exception when messed with "if setting the length is not allowed by
the implementation." Does that mean it's readonly in ie6 and not in
everything else, or what?

No. You can (reasonably confidently) delete options by reducing the
collection's length attribute, but you can't do that for a table's
rows collection. Maybe some browsers allow it, I've never tried, but
it shouldn't work.


[...]
Replacing console.log with alert in IE 6 returns "undefined".

I didn't really expect ie6 to be useful here. What else would that
show anyway? something like "[Object object]"?

No, undefined is OK if it's undefined.


[...]
I wasn't trying to determine whether chrome was doing things by
specification, I just wanted to quickly see what it called the
constructor and if it had any useful methods. Thanks for linking the
relevant docs though.

The OP may have received the impression that this is how to go about
detecting the types of things. I was just trying to point out that
while it may work in some browsers, it doesn't in others. Such
strategies are interesting to note, but should be tested (very) widely
before being used generally.

Maybe later... Don't have it handy.

It was rhetorical, I happen to have it handy but not later versions
(corporate networks that specify IE 6 don't like to upset things by
allowing later versions inside their ivory castle).

foo = [].slice.call(foo);
// did it work?
Maybe - in Firefox, yes. IE 6, no. Any Array method that requires
setting length (e.g. shift) will fail as it will try to set length,
which is readonly.

foo=[].slice.call(foo) doesn't change the length of the collection or
nodelist, so the resulting array 'foo' should have all Array.prototype
properties including a mutable length property. Or am I missing
something?

Possibly, just pointing out that because one method worked doesn't
mean that they all will in that browser, or at all in others.

What a wonderful world it would be if native Array methods could be
used to manipulate the DOM and pop, shift, unshift, etc. could be used
instead of appendChild, removeChild, etc. If DOM host objects behaved
like native objects, if...
 
G

Garrett Smith


A program that is at a point where it must ask that question is in a bad
situation.

Yep.

Instead, it is (in general) better to ask: Can `foo` do what I want it to?

It can blow up in certain cases, however, as:

typeof foo.slice

- was shown to *crash* safari 2.

[...]
foo=[].slice.call(foo) doesn't change the length of the collection or
nodelist, so the resulting array 'foo' should have all Array.prototype
properties including a mutable length property. Or am I missing
something?

Possibly, just pointing out that because one method worked doesn't
mean that they all will in that browser, or at all in others.

Array prototype methods used with a host object have
implementation-dependent results. They throw errors in all versions of
IE, though IE9 seems to have changed.

A feature test for CAN_SLICE_HOST_OBJ might use a try/catch to see if
the slice works and, from that, make a generalization that if a
collection is sliceable, that all collections are sliceable.
Whether or not that generalization gets lucky in IE9 has yet to be seen.

Garrett
 
G

Gregor Kofler

Am 2010-07-05 02:27, RobG meinte:
No, a collection.

[details and links snipped]

Thanks for pointing out all the details. Like nick I had assumed that
nodelists and (HTML)Collections are equivalent (at least "collection"
and "nodelist" is frequently used synonymously).

Gregor

(BTW: Your sig-seperator lacks a space.)
 
E

Evertjan.

Gregor Kofler wrote on 05 jul 2010 in comp.lang.javascript:
Am 2010-07-05 02:27, RobG meinte:
No, a collection.

[details and links snipped]

Thanks for pointing out all the details. Like nick I had assumed that
nodelists and (HTML)Collections are equivalent (at least "collection"
and "nodelist" is frequently used synonymously).

Let us be theoretical, and not just reading the specs.

Linguistically a "collection" is something that is collected.

If you collect a number of things into a list where the memebers of that
list can be accessed individually per item() or as an array member [],
it is unreasonable to allow the members of that list to be manipulated,
so you should not be able to delete or alter individual members or add
members to such list [you can alter the DOM, of course], nor perhaps[!]
should you be able to append properties or methods to that collection.

Asking a DOM structure for information with Javascript a logical returned
collection list is a collecion of nodes, a nodelist.

However other collections are possible in Javascript:

-- A list of CSS rules is a collection, but is it a nodelist? I do not
think so.

-- Request.form is a Javascript collection, but not part of the dom or
even the browser, as it is a serverside collection.

Collections in Javascript are never native, I think, in the sense that
they always collect information of the environment and not of Javascript
itself, so they are necessarily implementation dependent, and thy cannot
be defined or constructed by Javascript script code as you can an array
or an object, they can only be collected.
 
D

Dr J R Stockton

In comp.lang.javascript message <444b610d-9a18-4156-90d7-f863628c2542@m3
5g2000prn.googlegroups.com>, Mon, 5 Jul 2010 15:44:11, RobG
Yes, Google Groups trims it on posting. Unfortunately I only have
infrequent access to a news server so can't use a news reader to
ensure a proper signature.

If you have a newsreader and Internet access, and are not obstructed by
something vaguely like a firewall, then you can access Usenet with one
or more of the several (at least) free News servers, for example :

<td><a href="http://www.aioe.org/">AIOE</a>,
<a href="http://www.eternal-september.org">E-S.O</a>
<br><a href="http://news.solani.org/">solani</a>,
<a href="http://albasani.net/index.html.en">albasani</a>

The first two, at lease, appear to carry C.L.J.
 
G

Garrett Smith

In comp.lang.javascript message<444b610d-9a18-4156-90d7-f863628c2542@m3
5g2000prn.googlegroups.com>, Mon, 5 Jul 2010 15:44:11, RobG


If you have a newsreader and Internet access, and are not obstructed by
something vaguely like a firewall, then you can access Usenet with one
or more of the several (at least) free News servers, for example :

<td><a href="http://www.aioe.org/">AIOE</a>,
<a href="http://www.eternal-september.org">E-S.O</a>
<br><a href="http://news.solani.org/">solani</a>,
<a href="http://albasani.net/index.html.en">albasani</a>

The first two, at lease, appear to carry C.L.J.

Enough people have asked about posting through newsreaders, so it is
worth mentioning in the FAQ. Newsreaders, news servers and their
benefits can be mentioned in a new entry:

"1.3 How can I post to comp.lang.javascript"

It is best to post through a newsreader, such as Thunderbird.

Advantages of newsreaders that are not available in web interfaces
include folders for drafts and sent messages, options for filtering
spam, formatting, and more.

To access c.l.js through a newsreader you need a news server account.
The following news servers are all free:
http://www.eternal-september.org
http://www.aioe.org/
http://news.solani.org/
http://albasani.net/index.html.en

http://www.mozillamessaging.com/en-US/thunderbird/

It might also be a good idea to mention a few problems with Google
Groups, though perhaps that might best be added to:
<http://jibbering.com/faq/notes/posting/>
 
R

RobG

Unfortunately I am, so GG is it for now.


Thanks for those, I've also used news.sunsite.dk

Enough people have asked about posting through newsreaders, so it is
worth mentioning in the FAQ. Newsreaders, news servers and their
benefits can be mentioned in a new entry:

"1.3 How can I post to comp.lang.javascript"

It is best to post through a newsreader, such as Thunderbird.

I have a mostly hate relationship with Thunderbird. It's newsgroup
filtering leaves a lot to be desired - why can't I run a filter on
messages that have already arrived?

Anyhow, I find it pretty useless as a news reader and there aren't any
others worth using on Mac OS. Perhaps I'll switch to a Windows-based
agent.
 
R

Ry Nohryb

I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array.  I am
having great difficulty finding any good, comprehensive documentation on
javascript collections and their methods. Can anyone point me to a good
reference?

The most important difference between a JS array and a DOM collection
is that collections -unlike arrays- are live:

var collection= document.getElementsByTagName('div');
var item1= collection[collection.length-1];
document.body.appendChild(document.createElement('div'));
var item2= collection[collection.length-1];

item1 === item2
--> false
 
R

Ry Nohryb

I am working on a snippet and in my research I see that the options
property of the select object is a collection, not an array.  I am
having great difficulty finding any good, comprehensive documentation on
javascript collections and their methods. Can anyone point me to a good
reference?

The most important difference between a JS array and a DOM collection
is that collections -unlike arrays- are live:

var collection= document.getElementsByTagName('div');
var item1= collection[collection.length-1];
document.body.appendChild(document.createElement('div'));
var item2= collection[collection.length-1];

item1 === item2
--> false

Also:

var c1= document.getElementsByTagName('div');
var c2= document.getElementsByTagName('div');
c1 === c2
--> true
 
W

William Gill

The definitive reference is the W3C DOM Core spec, the above page has
a link to the DOM 3 Core reference, which doesn't seem to have changed
since Level 1.

However, the OP was asking about collections, which are a type of
NodeList that have some extra features:

DOM 2 HTMLCollection
<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506>

DOM 2 introduced the HTMLOptionsCollection interface, which is similar
to other collections but differs in that the namedItem method accepts
only an id and that length is not readonly, so it can be used to set
the number of items (e.g. as a quick way to remove all options, set
length to zero):

DOM 2 HTMLOptionsCollection
<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#HTMLOptionsCollection

The relevant HTML5 reference is:
<URL: http://www.w3.org/TR/html5/common-dom-interfaces.html#collections-0
Thanks Rob, and everyone. Good starting point. The DOM core refs I
have, though searchable (pdf) didn't help too much.
 
G

Garrett Smith

On 2010-07-06 09:41 AM, Dr J R Stockton wrote:
[...]
"1.3 How can I post to comp.lang.javascript"

It is best to post through a newsreader, such as Thunderbird.

I have a mostly hate relationship with Thunderbird. It's newsgroup
filtering leaves a lot to be desired - why can't I run a filter on
messages that have already arrived?

Anyhow, I find it pretty useless as a news reader and there aren't any
others worth using on Mac OS. Perhaps I'll switch to a Windows-based
agent.

OK, TB's at least better than GG I hope. What other readers are worth
recommending? Would a list of two or three be right for the FAQ?
 
R

RobG

Thanks Rob, and everyone.  Good starting point.  The DOM core refs I
have, though searchable (pdf) didn't help too much.

The W3C DOM specs take a bit of getting used to, they are segmented so
you have to learn what features are in which specification, such as
what is in Core and what is in HTML. And of course there is not always
a 1:1 realtionship between old and new specs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top