1

For example

var a = [1, 2, 3];
for (var i in a) {
    console.log(typeof i);
}

Output

string
string
string

I am a Python programmer, and I find it very unintuitive. Why is not an element evaluated to be a number instead?

Rose Kunkel
  • 3,102
  • 2
  • 27
  • 53
zyxue
  • 7,904
  • 5
  • 48
  • 74
  • 3
    `for in` will iterate over keys which it seems are converted to strings. `Object.keys(a)[0]` will return `"0"` – jcubic Jul 22 '16 at 15:01
  • 1
    Console log `i` and you will realise it's not the element. It's the indices. – Jonah Jul 22 '16 at 15:02
  • 1
    Do this: `var a = [1, 2, 3]; for (var i in a) {console.log(typeof a[i]);}` and you'll see numbers. – Gerardo Furtado Jul 22 '16 at 15:03
  • 1
    I see. `var a = [5, 6, 7]; for (var i in a) {console.log(i);}` still outputs `0 1 2`, which are the indices, NOT the elements. – zyxue Jul 22 '16 at 15:10
  • See [this question and its answers](http://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript) for the ways you loop through arrays in JavaScript. `for-in` isn't usually the right thing (it can be with sparse arrays). – T.J. Crowder Jul 22 '16 at 15:16

2 Answers2

5

You are looping over the keys of the object. Meaning the keys you are actually testing is "0", "1", "2".

You can see that here, if you also console the i. Also, if you console the value that is located at that index in the array, and test that, you will see that it is a number:

var a = [1, 2, 3];
for (var i in a) {
  console.log(i, typeof i, a[i], typeof a[i]);
}

In ES5, a new feature was added to arrays that loops through their values (and indexes): Array#forEach:

var a = [1, 2, 3];
a.forEach(function(v) {
  console.log(v, typeof v);
});

In ES2015+, for-of was added, which will loop through the values using a for-style loop:

// ES2015+ only!!
let a = [1, 2, 3];
for (let v of a) {
  console.log(v, typeof v);
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
KevBot
  • 17,900
  • 5
  • 50
  • 68
3

why the type of a number element in an array is evaluated to be a string in javascript

If you really mean the element, not the index, then the problem is that you're just looking at the type of the wrong thing. See KevBot's answer.


If you're asking why the indexes (0, 1, and 2) are strings rather than numbers, since array indexes are normally numbers, it's because standard arrays in JavaScript aren't really arrays at all, they're just objects with some special behavior:

An Array object is an exotic object that gives special treatment to array index property keys (see 6.1.7). A property whose property name is an array index is also called an element. Every Array object has a length property whose value is always a nonnegative integer less than 232. The value of the length property is numerically greater than the name of every own property whose name is an array index; whenever an own property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever an own property is added whose name is an array index, the value of the length property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the value of the length property is changed, every own property whose name is an array index whose value is not smaller than the new length is deleted. This constraint applies only to own properties of an Array object and is unaffected by length or array index properties that may be inherited from its prototypes.

Until ES2015, all object property names were strings. (Now they can be either strings or Symbols.) Array indexes are just property names that conform to a specific definition:

A String property name P is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232-1.

See also A myth of arrays (on my blog).

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875