views:

692

answers:

5

Namely, how does the following code:

var sup = new Array(5);
sup[0] = 'z3ero';
sup[1] = 'o3ne';
sup[4] = 'f3our';
document.write(sup.length + "<br />");

output '5' for the length, when all you've done is set various elements?

EDIT: Forget the comparison to using it like a hashmap. I think this was confusing the issue.

My 'problem' with this code is that I don't understand how length changes without calling a getLength() or a setLength() method. When I do any of the following:

a.length
a['length']
a.length = 4
a['length'] = 5

on a non-array object, it behaves like a dict / associative array. When I do this on the array object, it has special meaning. What mechanism in JavaScript allows this to happen? Does javascript have some type of property system which translates

a.length
a['length']

into "get" methods and

a.length = 4
a['length'] = 5

into "set" methods?

+1  A: 

If you're intending to implement objects with array-like access, the Array Mozilla dev center article is a great resource. Unfortunately I don't know the in depth details of Array implementation but there are a lot of details in that article.

Gareth
Sorry, at first glance I was thinking you could follow that page through to __defineSetter__ and __defineGetter__ but I'm not immediately sure that's the case
Gareth
You're url is screwy (no colon after https). Here's what you want:https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/ArrayAnd yes, you can follow that through to getter/setter documentation (see "Methods inherited from Object.prototype").
Matt Kantor
Also see: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/set_Operator
Matt Kantor
+1  A: 

Important to know is that when you do sup['look'] = 4; you are not using an associative array, but rather modify properties on the object sup. It is equivalent to sup.look = 4; since you can dynamically add properties on javascript objects at any time. sup['length'] would for an instance output 5 in your first example.

finpingvin
can property access / mutation be turned into a method call? if not, how would the 'length' property change if I've only modified the '0' and '1' properties?
Claudiu
An array is always an array, but in sup['look'] you are modifying the properties of the array-object, but when you do sup[0] you are accessing the array-index, not the object propery. I think tvanfosson explained it pretty good :)
finpingvin
+2  A: 

Everything in javascript is an object. In the case of an Array, the length property returns the size of the internal storage area for indexed items of the array. Some of the confusion may come into play in that the [] operator is overloaded. For an array, if you use it with a numeric index, it returns/sets the proper indexed item. If you use it with a string, it returns/sets the named property on the array object.

The actual underlying representation may differ between browsers (or it may not). I wouldn't rely on anything other than the interface that is supplied when working with it.

You can find out more about Javascript arrays at w3schools.com.

tvanfosson
ah this was my question: "In the case of an Array, the length property returns the size of the internal storage area for indexed items of the array.". So I guess my question is 'how do properties work?' - which I can answer myself. I just didn't know where to look!
Claudiu
(answer myself by googling, i meant - but i might still need help on this part)
Claudiu
is there any way to use this overloading in a javascript program I create myself, or is this just a special-case for arrays?
Claudiu
+1  A: 

Array object inherits caller, constructor, length, and name properties from Function.prototype.

eed3si9n
+1  A: 

To add to tvanfosson's answer: In ECMA-262 (the 3.0 specification, I believe), arrays are simply defined as having this behavior for setting properties (See 15.4.5.1). There's no general mechanism underlying it (at least as of now) - this is just how it's defined, and how javascript interpreters must behave.

Claudiu