for/in loop Array gotcha

I

Ian Osgood

I just wanted to let folks know of one more reason not to use for/in
loops on Arrays.

In the following code:

var u = [1,1]
for (var i in u)
print([i, i+2, i-0+2].join());
print(typeof(i) + ' ' + typeof(i-0));

0,02,2
1,12,3
string number

(i+1) does not obtain the expected results because i is a string!
Always use C-like loops when iterating arrays. JavaScript is not
Python!

Ian
 
P

pipe

var u = [1,1]
for (var i in u)
print([i, 2+i, -0+2+parseInt(i)].join());
print(typeof(i) + ' ' + typeof(i-0));



output left for readers to guess
 
M

Michael Winter

On 29/09/2005 16:49, Ian Osgood wrote:

[snip]
for (var i in u)
[snip]

(i+1) does not obtain the expected results because i is a string!

Of course, because property names are /always/ strings.

[snip]

Mike
 
A

aundro

Ian Osgood said:
I just wanted to let folks know of one more reason not to use for/in
loops on Arrays.

In the following code:

var u = [1,1]
for (var i in u)
print([i, i+2, i-0+2].join());
print(typeof(i) + ' ' + typeof(i-0));

0,02,2
1,12,3
string number

(i+1) does not obtain the expected results because i is a string!
Always use C-like loops when iterating arrays. JavaScript is not
Python!

Or, you could read the ecmascript spec, in order to find out what the
"for .. in" syntax actually does.

Your "advice" sounds more like a warning than anything else, but I'm
actually glad the "for .. in" syntax exists.

Arnaud
 
B

Baconbutty

Note also the following odd usage to test for the existence of a
property:-

var a={};
a.myProp=1;

var exists=(myProp in a);
 
A

aundro

McKirahan said:
[snip]
... I'm actually glad the "for .. in" syntax exists.

I didn't know of it before; thanks.

"The for...in statement is used to iterate a declared variable over every
property in a specified object. The code in the body of the for ... in loop
is executed once for each property."

Ok, here comes a little pedantry:

Some properties won't be iterated over (yet remain accessible) if they
have the 'DontEnum' attribute. How you can reach/set/clear those attributes
however, I absolutely have no idea.. Anybody has any idea?

(see P.65 of www.ecma-international.org/publications/standards/Ecma-262.htm)

Basically: you don't care about such properties, but heh, it's just
nice to know there can be 'hidden' properties.

Arnaud
 
A

aundro

Baconbutty said:
Note also the following odd usage to test for the existence of a
property:-

var a={};
a.myProp=1;

var exists=(myProp in a);

Is that proper JS? When I execute in SpiderMonkey:

----8<----
aundro@paddy:~$ js
js> var a={};
js> a.myProp=1;
1
js> var exists=(myProp in a);
3: ReferenceError: myProp is not defined
----8<----

*sob*


Regards,
Arnaud
 
M

Martin Honnen

Baconbutty said:
Note also the following odd usage to test for the existence of a
property:-

var a={};
a.myProp=1;

var exists=(myProp in a);

That snippet will give you an error, you need
var exists = "myProp" in a;

There is nothing "odd" about that in my view only that the 'in' operator
is not implemented in older browsers respectively the script engines
they come with, e.g. in Netscape 4 the 'in' operator use will give a
syntax error, the same for IE 5/Mac if I remember a recent discussion
here correctly.
 
I

Ian Osgood

McKirahan said:
[snip]
... I'm actually glad the "for .. in" syntax exists.

I didn't know of it before; thanks.

"The for...in statement is used to iterate a declared variable over every
property in a specified object. The code in the body of the for ... in loop
is executed once for each property."

http://www.devguru.com/Technologies/ecmascript/quickref/for...in.html

Nice reference. I note that this reference also mentions the use of
for..in on arrays, but without mentioning that the variable comes back
as a string instead of a number.

Ian
 
M

Martin Honnen

aundro said:
Some properties won't be iterated over (yet remain accessible) if they
have the 'DontEnum' attribute. How you can reach/set/clear those attributes
however,

Script code itself can't read or set that attribute, it is internal to
an implementation and if you have an application hosting a script engine
then you usually have access to set such attributes on the properties of
the host objects the application creates.
 
A

Arnaud Diederen

Martin Honnen said:
Script code itself can't read or set that attribute, it is internal to
an implementation and if you have an application hosting a script
engine then you usually have access to set such attributes on the
properties of the host objects the application creates.

That's indeed more or less what I was conceiving, but thanks a lot for
the clarification :)


Arnaud
 
L

Lasse Reichstein Nielsen

[property attributes like DontEnum]
Script code itself can't read or set that attribute,

Almost correct. There is Object.prototype.propertyIsEnumerable that
allows you to read one of the three attributes (the other two being
ReadOnly and DontDelete, which can't be read, but might be discoverable
by trying to do it and catching the exception :)

/L
 
M

Michael Winter

On 30/09/2005 18:57, Lasse Reichstein Nielsen wrote:

[snip]
(the other two being ReadOnly and DontDelete, which can't be read,
but might be discoverable by trying to do it and catching the
exception :)

No exceptions should be thrown if the delete or assignment operators are
used on DontDelete or ReadOnly properties, respectively. The operation
should silently fail (though the delete operator should evaluate to false).

Mike
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top