1

I was just testing out the Java Script for...in ( just a newbie :P :D ).

I tried the following code:

var arr=[];
arr['n1']='name1';
arr['n2']='name2';
arr['n3']='name3';
arr['n4']='name4';

var i,j;

for(i in arr)
{
    for(j in i)
        document.writeln(j+"-");
}

and the output was:

0- 1- 0- 1- 0- 1- 0- 1-

I was wondering why am I getting an output like this.

The for...in loop if tried to output the 'i' instead of 'j' I'm getting the index names.

When I checked the typeof 'j' I got it as String.

Please help me understand the output.

AtheistP3ace
  • 9,611
  • 12
  • 43
  • 43
  • 2
    You should start by [not using `for…in` enumerations on arrays!](https://stackoverflow.com/q/500504/1048572) and [not abusing arrays as objects](http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/). `i` will be property names (strings), and using `for in` on them will yield string indices as property names… – Bergi Feb 24 '16 at 17:44
  • 1
    try `for (var i in 'n1') console.log(i)` – dfsq Feb 24 '16 at 17:45
  • What do you actually want to achieve? How did you expect your code to work (what output did you expect)? – Bergi Feb 24 '16 at 17:45
  • @Bergi Hi, yeah I figured it now it's really a bad choice :P Also https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in I just was curious to know what is happening that's all :) I learned that for..in is intended for iterating over an object and array being a list like objects thought I could try for...in on it too :P I was wondering why I'm getting a 0 / 1 when i try to iterate over 'i' – Sreejith C M Feb 24 '16 at 17:48
  • Also there's a nice answer here http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea – Nikki9696 Feb 24 '16 at 17:48

3 Answers3

0

This is how your code will work,

var arr=[];
arr['n1']='name1';
arr['n2']='name2';
arr['n3']='name3';
arr['n4']='name4';

var i,j;

for(i in arr) {
 // i will be the keys, n1,n2,n3,n4
 // And those keys are strings.
 // You are traversing over the enumerable properties of strings "n1","n2"..
 // So enumerable property of "n1" will be 0 and 1. 
 // So it is getting printed in the internal loop
 for(j in i) {
  document.writeln(j+"-");
 }
}

It is better not to use for in loop with arrays since it will iterate through all the enumerable properties throughout the prototype chain. Use a simple for loop instead. Or just use .hasOwnProperty() to ensure the enumerable property belongs to the immediate/own prototype chain.

Rajaprabhu Aravindasamy
  • 66,513
  • 17
  • 101
  • 130
0

Everybody seems to want to answer a question you didn't ask. So here is the answer to your question.

When you use for..in on an array you will just get the array keys. In your case "n1", "n2", etc..

When you use for..in on a string you will get the indices of that string. In your case you have a bunch of two character strings so you will get 0 & 1 for each.

To see what is going on try this:

for (i in 'test') {
    console.log(i)
}

output: 0 1 2 3

because it is a 4 character string.

But all the comments are correct. Don't do this. Read some of the links they provided.

nickles80
  • 1,101
  • 8
  • 10
0

Javascript doesn't have an associative arrays.
You can't fill a regular array in such way: arr['n1']='name1';.

If you use a named index, JavaScript will redefine the array to a standard object. After that, all array methods and properties will produce incorrect results.

var arr=[];
arr['n1']='name1';
arr['n2']='name2';
arr['n3']='name3';
arr['n4']='name4';
var x = arr.length;         // arr.length will return 0
var y = arr[0];             // arr[0] will return undefined

As for the for-in loop - this loop has a very special purpose: it enumerates the named properties of any object.

for(i in arr)
{
    for(j in i)
        document.writeln(j+"-");
}

The 'parent' loop will iterate the named properties, such as n1, n2 etc. The nested loop expects the second operand to be an object: i should be an object in this expression (j in i). But the actual value is a string (n1 ,n2, n2). Therefore, Javascript will create Primitive Wrapper Object for every string on each iteration behind the scenes:

...
for(j in i) // actually would be (for j in new Object('n1'))
   // console.log(new Object('n1'));
   // String {0: "n", 1: "1", length: 2, [[PrimitiveValue]]: "n1"}
   document.writeln(j+"-");
...

As you can see, a primitive wrapper object has two "numbered" properties for each string. That's way it gives to you the output:

0- 1- 0- 1- 0- 1- 0- 1- 
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105