0

I've been really surprised that, in Javascript:

> vals = ["a", "b", "c"]
> for (v in vals) console.log(v + 1)
01 
11 
21 

this because:

> for (v in vals) console.log(typeof(v))
string
string
string

so I'm forced to do something like:

> for (v in vals) console.log(parseInt(v) + 1)
1 
2 
3 

Why this happens?

I know I can do

> for (var v = 0; v < vals.length; v++) console.log(v + 1)
1 
2 
3 

but being used with python my mind is set with for ... in ... iteration

neurino
  • 11,500
  • 2
  • 40
  • 63
  • 2
    *"...but being used with python my mind is set with `for ... in ...` iteration"* Python is irrelevant here. This is JavaScript. All object properties are strings. Use a `for` loop. –  Nov 08 '14 at 17:10
  • ...there are several reasons in JS to us `for` instead of `for-in` on Arrays. However, if you really want to do it that way, you can shorten it to `console.log(+v + 1);` –  Nov 08 '14 at 17:14

1 Answers1

3

My friend, behold the wonder and curse of prototypical inheritance. What you are iterating over with for..in isn't an array. You are iterating over an Array object. Take a look at the doc:

Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.

Because the order of iteration is implementation dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index (or Array.forEach or the for...of loop) when iterating over arrays where the order of access is important.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

So what you are dealing with are enumerable "integer names" of properties in an Array object, not numerical order.

EDIT for v in array in JavaScript isn't equivalent to for v in list in python. It's equivalent to for k, v in dict.iteritems() but k is implicitly given to you as a string with integer name so to speak, i.e. "1", "2", "3", etc. I think it's counter-intuitive as well from an OO standpoint. How can a list/array be a dict-like object? But from a prototypical standpoint, so long as anything inherits from Object.prototype, it can be considered an Object with keys and properties.

Lim H.
  • 9,870
  • 9
  • 48
  • 74