By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,605 Members | 2,153 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,605 IT Pros & Developers. It's quick & easy.

for/in loop Array gotcha

P: n/a
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

Sep 29 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a
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

Sep 29 '05 #2

P: n/a
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

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Sep 29 '05 #3

P: n/a
"Ian Osgood" <ia**@quirkster.com> writes:
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.

Ian


Arnaud
Sep 30 '05 #4

P: n/a
"aundro" <ad@ionicsoft.nospam.please.com> wrote in message
news:87************@paddy.ionicsoft.com...

[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/.../for...in.html
Sep 30 '05 #5

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

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

var exists=(myProp in a);

Sep 30 '05 #6

P: n/a
"McKirahan" <Ne**@McKirahan.com> writes:
"aundro" <ad@ionicsoft.nospam.please.com> wrote in message
news:87************@paddy.ionicsoft.com...

[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 http://www.ecma-international.org/pu...s/Ecma-262.htm)

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

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


Arnaud
Sep 30 '05 #7

P: n/a
"Baconbutty" <ju****@baconbutty.com> writes:
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
Sep 30 '05 #8

P: n/a


Baconbutty wrote:
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.
--

Martin Honnen
http://JavaScript.FAQTs.com/
Sep 30 '05 #9

P: n/a

McKirahan wrote:
"aundro" <ad@ionicsoft.nospam.please.com> wrote in message
news:87************@paddy.ionicsoft.com...

[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/.../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

Sep 30 '05 #10

P: n/a
>>That snippet will give you an error, you need
var exists = "myProp" in a;


Oops, thank you for that.

Sep 30 '05 #11

P: n/a

aundro wrote:
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.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Sep 30 '05 #12

P: n/a
Martin Honnen <ma*******@yahoo.de> writes:
aundro wrote:
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.


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

--

Martin Honnen
http://JavaScript.FAQTs.com/

Arnaud

Sep 30 '05 #13

P: n/a
Martin Honnen <ma*******@yahoo.de> writes:

[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
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Sep 30 '05 #14

P: n/a
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

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Sep 30 '05 #15

P: 1
When using prototypes...

As per Brendan Eich's proposal back in 2004(Enumeration of extended properties of Array and Object prototypes), you can use the obj.hasOwnProperty() method to check against inherited properties(prototypes). Yea this means you have to modify your for...in loops here and there, but if you want to use your objects this way then at this point you are going to have to modify your code anyway.

It would be nice to have that DontEnum property available for modding, but until it is, this or a custom Object is your only way around the problem. And from my understanding the for...in shouldn't be used anyway on sparse arrays in the first place. You could look at it like this, if the Object can't evaluate foo.length then for all intents it's not an array so don't use for...in iteration use for...i. Long story short, way too many people are using the wrong iteration constructs in their code.

FYI : about the foo.propertyIsEnumerable() being discussed here, this is taken from 'javascript: The Definitive Guide, 4th Edition', By David Flanagan
ECMAScript specification states that propertyIsEnumerable( ) does not examine the prototype chain, which means that it only works for local properties of an object and does not provide any way to test the enumerability of inherited properties

I am really not sure why this is such a huge issue for everyone, I guess I should say RTFM and pass it along
Feb 20 '06 #16

This discussion thread is closed

Replies have been disabled for this discussion.