简体   繁体   中英

JavaScript assignment with operation *= conundrum

Following code is giving me a big time headache

        var somearr = [1, 2, 3];

        function operations() {
             for (var i = 0; i < somearr.length;) {
                   //alert (somearr[i++] *= 2); // statement-1

                    alert(somearr[i++] = somearr[i++] * 2); //statement-2

        }

   }

  operations();

Conceptually statement-1 and statement-2 are same (see the comments in the code above). I know that somearr[i++] is evaluated once in statement-1 and twice in statement-2. However what I don't understand is that output of statement-1 (after recursive iteration) is [2,4,6] which is expected but the output of the recursively executing statement-2 is [4,NaN] (totally confused with this output).

On top of that when I try to debug this code using Visual Studio and put a break point in front of statement-2 when the break point is hit I just stay at the statement-2 (forever) without debugging the code any further and noticed (nearly after every 10 to 15 seconds) that index value i++ automatically gets incremented without even debugging the code further (as I said earlier) , I'm kinda totally stumped that how come visual studio debugger auto increments index i value without letting me debug the code (that is, recursively iterating all the index values) and stops increment once the value if i++ = 3.

Your issue is that you're incrementing i twice in statement 2. So multiplying by null (which is what you get when you pull an index not in your array) returns NaN.

It is best practice to increment inside your for-loop like this:

for (var i = 0; i < somearr.length; i++) {
  //somearr[i] *= 2; // statement-1

  //somearr[i] = somearr[i] * 2; //statement-2
}

Now both statements work.

your code was as follows:

for (var i = 0; i < somearr.length;) {
    somearr[i++] = somearr[i++] * 2;
}

At execution we evaluate somearr[i++]: i = 0, somearr[0] = 1 We set this to equal to somearr[1] * 2 (somearr[1] since we incremented after our first evaluation). Therefore the first index of somearr becomes 4, and i is currently set to 2, since we incremented again.

Now we check somearr[2], which gives us 3. We set this value to equal somearr[3] * 2. But somearr[3] is null, because we are now past the array's indices. This evaluates to NaN because 2*null is NaN.

our i is now 4, because we incremented again, and our array is [4, NaN]. We stop looping because i = 4, which terminates the for-loop

the output of statement-1 is [2,4,6] which is expected

Yes. If we unroll the loop, we get

var somearr = [1, 2, 3];
somearr[0] *= 2; // somearr[0] = somearr[0] * 2;
somearr[1] *= 2; // somearr[1] = somearr[1] * 2;
somearr[2] *= 2; // somearr[2] = somearr[2] * 2;
// i (3) is no more smaller than somearr.length (3) after the third iteration

the output of executing statement-2 is [4,NaN] (totally confused with this output).

Actually the output of somearr is [4, 2, NaN] . Why is that? Because i++ is evaluated twice per body execution. The loop now unrolls to

var somearr = [1, 2, 3];
somearr[0] = somearr[1] * 2; // 2 * 2
somearr[2] = somearr[3] * 2; // undefined * 2
// i (4) is no more smaller than somearr.length (3) after the second iteration

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM