Why does this simple loop not work as expected?

You can expect the following to be printed a , b , c .

 var i, rowName; for (i = 0; i < 3; i++, rowName = ['a', 'b', 'c'][i]) { console.log(rowName); } 

Instead, however, it prints undefined , b , c . Why?

To clarify: I know how to do this job; which I wonder why the above does not work.

+5
source share
4 answers

The reason it prints undefined , b , c is due to how it works for the loop .

 for (initialization; condition; final expression) 

Let me break the for loop.

initialization: i = 0

condition: i < 3

final expression: i++, rowName = ['a', 'b', 'c'][i]

When your loop is entered first, i set to 0 . This is the initialization step. Then the state step i < 3 checked. This is done before each iteration to decide whether to continue the loop. After each cycle, the final expression is evaluated. In your example, you increment i to set rowName equal to the element in ['a', 'b', 'c'] based on the current index.

In your case, in the first iteration, rowName is undefined , because the final expression has yet to be evaluated. Each iteration after that behaves as you would expect, since the final expression has already been pre-evaluated.

+5
source

If you want to make a complex single-line loop style, the โ€œcorrectโ€ syntax is:

 var array = ['a', 'b', 'c']; for (var i = 0, rowName; rowName = array[ i++ ]; ) { console.log(rowName); } 

Pay attention to the ending ; t22 cycle declarations. There is a technically empty statement after ; where you usually do i++ .

In this case, the "condition" of the for loop uses the Javascript assignment operator. If you have a code like this:

 var a; if( a = 1 ) { // Note this is assignment = not comparison == console.log('true'); } 

He will keep a log of "true". What for? Since inside the expression a = 1 really returns 1 . And 1 is โ€œtrueโ€, which means that it evaluates true in a logical context such as an if .

The opposite is also true if your meaning is false:

 var a; if( a = 0 ) { console.log('true'); } 

It will not register, because a = 0 returns 0 (and also assigns 0 to a ). And 0 is false.

This brutal for-loop syntax is for specific conditions only:

  • If any of the elements of the array is "falsey" ( null , undefined , "" , etc.), it will terminate the loop prematurely due to the way the operators work, as described above.
  • This suggests that you do not need the loop index i . It will be disabled by 1 for each iteration of the loop, because i++ runs before the for block. That is, the first time the for body is executed, i will be 1, not the declared initial value 0.
  • The only advantage of this pattern is the storage of several bytes. It is not used at all in the real world because of the above two pitfalls.
+2
source

Think you want this?

 var i, rowName; for (i = 0; i < 3; i++){ rowName = ['a', 'b', 'c'][i]; console.log(rowName); } 
0
source

You reassign rowName at each step of the loop and start with undefined . Here is what you can do:

 for(var i=0,rowName=['a','b','c'],l=rowName.length; i<l; i++){ console.log(rowName[i]); } 

or something like:

 var rowName = ['a', 'b', 'c']; for(var i=0,l=rowName.length; i<l; i++){ console.log(rowName[i]); } 

The real problem is that the third condition inside for(assign; test; execute) does not execute until one test loop is executed. If test fails, execute will never happen. If test passes execute really begins after the first pass of the loop.

0
source

Source: https://habr.com/ru/post/1235848/


All Articles