2

A very simple question, but I could not find the answer anywhere. Check the following code.

var myArray = [0,1,2,3,4,5,6,7,8,9];

for(i=0; i < myArray.length; myArray++){
 console.log("Loop iteration step : "+i);
}

console.log("After array increment : " + myArray);

The myArray++ is not a typo. As you can see, the code will only run once. And after running it once, the loop terminates and myArray becomes NaN.

What is happening here to the array? How can an array become a NaN?

P.S: OK, more information since everyone is curious why myArray++ is not a typo. Yes, it was a typo at first. That's how I came up with this But that's not the problem I have here. I added the complete loop because I wanted to show the place I came up with this error.

6
  • You may read on type conversions: w3schools.com/js/js_type_conversion.asp Commented Jan 12, 2018 at 9:36
  • 1
    Seriously myArray++ is not a typo? So you do want to myArray++ and then you are wondering why it runs only once? :D Maybe you could then explain what you would like this code to do? Commented Jan 12, 2018 at 9:37
  • i++ instead of myArray++ why? Commented Jan 12, 2018 at 9:38
  • 1
    It's not a typo in the context of this question. Yes, in the real world, if I wanted to iterate the array, it's a typo. Commented Jan 12, 2018 at 9:43
  • 2
    You don't need the loop to demonstrate the problem. Just myArray = [1, 2, 3]; myArray++; console.log(myArray); Commented Jan 12, 2018 at 9:47

3 Answers 3

5

EDIT: I have fixed some (shameful) misconception in terms of what the increment operand does. I fell into the same mistake of not looking up the actual docs. I hope this helps other users not fall upon the same mistake. (thank you for pointing that out @gurvinder372.)

I highly recommend you look up the documentation for "Increment" , the first sentence explains what's happening:

The increment operator increments (adds one to) its operand and returns a value.

One would think the Increment operator ++behaves as following:

myArray++ ---> myArray = myArray + 1;

When JavaScript evaluates myArray + 1 anything can come off that. In this case just try it out:

var myArray = [0,1,2,3,4,5,6,7,8,9];
myArray + 1
"0,1,2,3,4,5,6,7,8,91"

You could assume then it assigns a string back to myArray , when increment operator in the for loop evaluates, it determines that value is not a number, hence the NaN, and for loop exits before second iteration when condition i<NaNevaluates to false. Try it out:

var a = "a";
a++;
NaN

But that's not entirely correct (I messed up in terms of what myArray++ actually does under the hood, and it's better to understand what it's actually happening). Looking at the actual specs for Postfix Increment operator, we get the following:

Steps

myArray++

  1. lhs = myArray
  2. oldValue = Number(myArray)

    oldValue = NaN

  3. newValue = oldValue + 1

    newValue = NaN + 1

    newValue = NaN

  4. myArray = NaN
  5. The Postfix Increment operator returns oldValue, NaN and now myArray=NaN

So what you end up with in your for loop after the first iteration when the Postfix Increment operator runs is:

for ([initialization]; [condition]; [final-expression])
    statement

for ([initialization]; i<myArray.length; NaN)
    statement

for ([initialization]; i<NaN.length; NaN)
    statement

for ([initialization]; i<undefined; NaN)
    statement

for ([initialization]; false; NaN)
    statement

I hope this helps clear up a bit what's happening in every step and part of the loop and why myArray ends up with value NaN.

Here's something interesting to try and see if you understand why in this infinite loop your myArraygets to stay as [...] but counter is NaN after second call.

var myArray = [1,2,3,4,5,6,7,8,9];
var counter = myArray;
for(let i=0; i<myArray.length; counter++){
    console.log("Infinite calls. Never leaving and counter is " + counter);
   // i++; if you don't want to eat up that infinite loop.
}

Answer

You get the infinite loops because your expression i<myArray.length will always evaluate to True since i is never modified. Meanwhile, counter will go to NaNafter first iteration because of what was explained at the start of the post. myArray stays cool because the Postfix Increment is done upon counter. Why does this loop iterate but the one you did, does not? Because in the one you did you end up changing the value of myArrayinto NaNforcing the expression in the loop i<NaN.length---> i<undefined to be false after first iteration, causing the loop to exit.

Sign up to request clarification or add additional context in comments.

4 Comments

myArray++ is actually myArray = myArray + 1; No
The for loop won't change "0,1,2,3,4,5,6,7,8,91" to NaN. The increment operator itself is doing that, it doesn't do concatenation.
Yes, the increment operator itself is doing that.. then just compares 0,1,2,3,4,5,6,7,8,91 < 10(myArray.length) which returns false. So for loop will finished.
Thank you for going in to the extent of explaining why the for loop stop fro after a single iteration as well. That part I understood before posting the question, my curiosity was regarding an array being a NaN. It's solved now.
4

As per spec for Postfix Increment Operator

  1. Let oldValue be ToNumber(GetValue(lhs)).

And

var myArray = [0,1,2,3,4,5,6,7,8,9];
Number(myArray) //NaN

Hence myArray++ => NaN

Demo

var myArray = [0,1,2,3,4,5,6,7,8,9];
console.log( "Just increment using postfix operator ", myArray++ );

myArray = [0,1,2,3,4,5,6,7,8,9];
console.log( "Number conversion ", Number(myArray) );

Comments

2

When you do ++ and if the variable is not of type number, it will be converted to string using toString and then converted to number.

Object.toString returns [object Object], so Number('[object Object]') returns NaN

Also when you do ++ is a short hand for += so myArray++ is equal to myArray = myArray + 1;. Now that your myArray is not an array, it does not have property length and it returns undefined (as everything in JS is an object) and the loop breaks.


As rightly pointed out by @barmar, Array.toString returns array.join. So it is equal to Number("0,1,2..."). Since comma(,) is not a valid numeric character, it returns NaN. Also, when value is compared to NaN, it returns false hence breaking the loop.

Sample:

var myArray = [0,1,2,3,4,5,6,7,8,9];
console.log(myArray.toString())
console.log(Number(myArray.toString()))
console.log(1<NaN)

1 Comment

Array.toString returns this.join(','), i.e. "1,2,3,4,5,6,7,8,9,10", not [object Object]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.