If you think a bug might affect users in the 57 release, please set the correct tracking and status flags for Release Management.

Length of associative arrays is reported as zero (0)

VERIFIED INVALID

Status

()

Core
JavaScript Engine
P3
major
VERIFIED INVALID
17 years ago
16 years ago

People

(Reporter: kens, Assigned: rogerl (gone))

Tracking

Trunk
x86
Windows 2000
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

17 years ago
var x = new Array();
x["foo"] = "bar";
x["bar"] = "baz";
x.length

This script produces: "0"

Shouldn't associative arrays have a length attribute which reports the number 
of keys contained in the array's hash table?

Comment 1

17 years ago
From the ECMA3 spec: 


15.4 Array Objects

Array objects give special treatment to a certain class of property names. A 
property name P (in the form of a string value) is an array index if and only if 
ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2 32 -1.

Every Array object has a length property whose value is always a nonnegative 
integer less than 2 32 . The value of the length property is numerically 
greater than the name of every property whose name is an array index;
whenever a property of an Array object is created or changed, other properties 
are adjusted as necessary to maintain this invariant. Specifically, whenever a 
property is added whose name is an array index, the length property is changed, 
if necessary, to be one more than the numeric value of that array index; and 
whenever the length property is changed, every property whose name is an array 
index whose value is not smaller than the new length is automatically deleted. 

This constraint applies only to properties of the Array object itself and is 
unaffected by length or array index properties that may be inherited from its 
prototype.

Comment 2

17 years ago
Have to mark this one as invalid. According to the spec, the length property
of an Array object counts the number of properties whose name P is an 
"array index" as defined by the spec. This means in particular,


                   P == ToString(ToUint32(P))    


In short, P must be numerical. So, for example, if we do this: 


var x = new Array();
x['0'] = 'bar';
x[1] = 'baz';
x['a'] = 'foo';
x.length;


the output will be 2, not 3, because both '0' and 1 are 
ECMA "array indices", but 'a' is not.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 17 years ago
Resolution: --- → INVALID
(Reporter)

Comment 3

17 years ago
Okay, this is all cool. So the only way to find the number of keys in 
an "associative" array in JavaScript is by iterating over its contents and 
maintaining a count? e.g.:

var counter = 0;
for(x in a) {
  counter++;
}

Forgive me for asking, but is there a better way?
(Assignee)

Comment 4

17 years ago
Verifying Phil's analysis.

I'm afraid I can think of no better way of counting the properties of a generic 
object - and the code snippet you show runs afoul of properties in the 
prototype, too. You need :
for (x in a) if (a.hasOwnProperty(x)) counter++;

bleagh!
Status: RESOLVED → VERIFIED

Comment 5

17 years ago
See bug 57048 for more info on this -
You need to log in before you can comment on or make changes to this bug.