I wrote a this simple code in js.
var n=10;
for (i=1;i=n;i++){
console.log('avinsyh');
}
But the loop executes greater than 2000 and crashing the browser.Why this is happening so?
Note: If I Execute this:
var n=10;
for (i=1;i<n;i++){
console.log('avinsyh');
}
Then the javascritpt outputs the correct results
It's the assignment in the comparison part of the for loop, which makes an infinite loop. i becomes always n and evaluates to true.
for (i = 1; i = n; i++){
// ^^^^^
var n = 10,
i;
for (i = 1; i <= n; i++){
document.write('i: ' + i + '<br>');
}
in your first for loop , i=n will set i equal to the value of n and thus return a truthy value(as n is not 0) and you get a infinite loop.
In your for loop you are assinging the value i = n which is always true and hence results in infinite loop.
The condition expression is evaluated. If the value of condition is
true, the loop statements execute. If the value of condition is false,
the for loop terminates. If the condition expression is omitted
entirely, the condition is assumed to be true.
In your second case you are comparing the value of i on each iteration and hence you are getting the expected result.
The basic syntax of for loop is:
for ([initialExpression]; [condition]; [incrementExpression])
statement
So in your first case you are not providing the [condition] rather it is an assignment.
Related
I was trying to make a for loop that increments through the numbers 1 - 4 and print them, but when I printed the value of i after the loop, my code outputs 5.
for (i = 1; i < 5; i++) {
document.write(i + "<br>"); //Outputs numbers 1 - 4
}
document.write("New i: " + i); //Outputs 5
How is this possible if i can only increment up until its value is 4?
When you declare a variable in a loop statement, it stores the variable in the same scope as the loop. Loops increment (i++) at the end of the loop, then check the condition (i < 5) to see if they should repeat. After the loop, the variable i still exists. See the snippet below for a play-by play.
Also, you should use the var keyword when declaring i, otherwise, the variable is stored in the global scope (which is bad practice).
//variable i is captured here (with the var keyword)
for(var i = 1; i < 5; i++) {
//for the fourth iteration, i === 4
//so it prints 4.
document.write(i);
//i++ happens right now, so i now is 5.
//then the loop checks the condition to see if it
//should continue. i isn't less than 5, so the loop breaks.
}
//and the value of i is still 5. so this prints 5.
document.write('</br>' + i);
You could move the final-expression part into the condition part of the for statement, where the increment takes place only if the value is smaller than 4.
var i;
for (i = 0; i < 4 && ++i;) {
console.log(i); // 1 ... 4
}
console.log('last value', i); // 4
The test clause of i < 5 is evaluated at the beginning of each loop; if it is false, the loop exits (leaving the value at 5). The i++ part always happens at the end of an iteration, meaning that after the number 4 has been processed in the loop, it increments it to 5, then it loops to the top of the loop where it checks the condition again (i<5) which it fails, but the value of i is not reversed back to 4.
The condition of the loop block to be processed is i < 5, thus i must be less than 5 for the statements and expressions within it to be evaluated
You increment i by 1 with each pass
When i equals 4, you increment it by 1 again such that i will be equal to 5. i < 5 is no longer true, so within the loop block is not executed
Nothing turns i back one increment; so it retains it after the loop
You can apply unique ways, but generally the first and last example below is the common approach:
var log = console.log;
// Example 1: Decrease Loop Iterator After
for (var i = 1; i < 5; i++)
log(i);
log('New i:', --i); // 4
// Example 2: Count in conditional
var count = 0;
for (var i = 1; i < 5 && ++count; i++)
log(i);
log('New i:', count); // 4
// Example 3: Count in loop body
var count = 0;
for (var i = 1; i < 5 && ++count; i++)
log(i);
log('New i:', count); // 4
you have declared i as global variable.
That's how the for loop works.
for (initialization, condition, increment/decrement ) {
}
You have initialized with 1 and it satisfies the condition i<5 so it enters the loop and prints i. after then it performs the increment/decrement operation and increases the value by 1 in your case. So while i=4 and i<5 it enters the loop and prints 4, but after then it performs increment operation and increase the value of i to 5.
In the next step, as the condition i<5 is not satisfied , so it breaks the loop and go to the last statement, where you are printing i, that is 5.
Hope it is clear now.
var array = [1, 2, 3, 4];
array.forEach(function(value) {
document.write(value + "<br />");
});
document.write("Values processed: " + array.length);
No, I‘m not kidding. Use arrays whenever you can, they will spare you a lot of trouble. The side effect you‘re in fact asking for can cause hard-to-track bugs (i looks like being meant for the loop only, imagine tons of lines between the loop and the last document.write). And there‘s the off-by-one error problem with for loops.
You‘ll probably anyway end up with an array once your code starts doing meaningful stuff (you don‘t want to count up to 4, do you?). So do yourself a favor an embrace all those powerful Array methods.
please use count variable because i value increases after each statement execution. i.e after your loop is finished execution i will be always 5
var count=0;
for (i = 1; i <5; i++) {
document.write(i + "<br>"); //I increases after these statement execution so it will be 5 at last
count=count+1;
}
document.write("New i: " + count); //Outputs 5
One might expect the following to print out a, b, c.
var i, rowName;
for (i = 0; i < 3; i++, rowName = ['a', 'b', 'c'][i]) {
console.log(rowName);
}
Instead, however, it prints out undefined, b, c. Why?
To clarify: I know how to make this work; what I'm curious about is why the above doesn't work.
The reason it prints undefined, b, c is because of how a for loop works.
for (initialization; condition; final expression)
Let's break down your for loop.
initialization: i = 0
condition: i < 3
final expression: i++, rowName = ['a', 'b', 'c'][i]
When your loop is first entered, i is set to 0. This is the initialization step. Then the condition step, i < 3, is checked. This is done before every iteration to decide whether or not to continue looping. After each loop, the final expression is evaluated. In your example, you increment i before setting rowName equal to an element in ['a', 'b', 'c'] based on the current index.
In your case, on the first iteration, rowName is undefined because the final expression is yet to be evaluated. Every iteration thereafter behaves as you would expect since a final expression has already been previously evaluated.
If you want to do the tricky one-line for loop style, the "correct" syntax is:
var array = ['a', 'b', 'c'];
for (var i = 0, rowName; rowName = array[ i++ ]; ) {
console.log(rowName);
}
Notice the ending ; of the for loop declaration. There's technically an empty statement after the ; which is where you normally would do i++.
In this case, the "condition" of the for loop is taking advantage of the Javascript assignment operator. If you have some code like this:
var a;
if( a = 1 ) { // Note this is assignment = not comparison ==
console.log('true');
}
It will log "true". Why? Because inside of an expression, a = 1 actually returns 1. And 1 is "truthy," meaning it evaluates to true in a boolean context like an if statement.
The opposite is also true, if your value is falsey:
var a;
if( a = 0 ) {
console.log('true');
}
It will not log, because a = 0 is returning 0 (as well as assigning 0 to a). And 0 is falsey.
This whacky for-loop syntax is only for certain conditions:
If any of the array elements are "falsey" (null, undefined, "", etc) it will prematurely terminate the loop, because of how operators work as mentioned above.
This assumes you don't care about the loop index i. It will be off by 1 for every iteration of the loop, because i++ is executed before the for block. That is, the first time your for body executes, i will be 1, not its declared starting value of 0.
The only benefit of this pattern is saving a few bytes. It's generally not used in the real world because of the above two pitfalls.
I think you want this?
var i, rowName;
for (i = 0; i < 3; i++){
rowName = ['a', 'b', 'c'][i];
console.log(rowName);
}
You are reassigning rowName at each step of the loop and it's undefined to begin with. Here's 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 issue is that the third condition inside for(assign; test; execute) does not execute until until one test of the loop is satisfied. If the test fails execute never happens. If the test passes execute really begins after the first pass of the loop.
I'm a bit stumped by the exact order of execution of a particular for loop I'm playing with, in Codepen. Check out these two loops, which both do the same thing:
var a = ['orange','apple'];
for (var i=0; i<2;i++) {
alert(a[i]);
}
for (var j=0, fruit; fruit = a[j++];) {
alert(fruit);
}
You can see this in action here: http://codepen.io/nickbarry/pen/MYNzLP/
The first loop is the standard, vanilla way of writing a for loop. As expected, it alerts "orange", then "apple".
I wrote the second loop using a suggestion from MDN (search for "idiom", here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript ).
It works, but I don't quite understand why. My understanding of for loops, which is obviously incorrect in some way (more than one way?) is that:
* The for loop evaluates the truthiness of the second expression before it runs the first time. So it seems that when the for loop is evaluating the truthiness of the second expression, it should increment j before setting the value of fruit. So the first time through the loop, fruit should equal "apple".
* And the loop should only run once, because after the first time through, when it's evaluating the second expression again to see if it's still true, it should once again increment j before it returns a value to fruit, and since there is no value at index position 2, it should return a falsy result, and exit the loop.
I don't understand what actually IS happening. Does the for loop run once before the second expression is evaluated? But that seems impossible, because if that happened, the alert would alert nothing the first time through, since fruit wouldn't yet have a value.
Also, the author of the MDN article seemed to like the second way of writing the loop - is there a reason that way is better? It uses fewer characters, which is good, I guess. Does skipping the third expression in the for loop save significant time? Or is it just a "it's cool because it's clever" sort of thing?
for (var j=0, fruit; fruit = a[j++];) {
alert(fruit);
}
In pseudocode is equal to:
initialize j = 0 and fruit = undefined
assign fruit = a[j] (j = 0, fruit = 'orange')
j = j + 1 (j = 1)
check fruit for being truthy (true)
alert(fruit) ('orange')
assign fruit = a[j] (j = 1, fruit = 'apple')
j = j + 1 (j = 2)
check fruit for being truthy (true)
alert(fruit) ('apple')
assign fruit = a[j] (j = 2, fruit = undefined)
j = j + 1 (j = 3)
check fruit for being truthy (false)
exit loop
Important note:
The postfix unary ++ operator works as:
We return the current value of the variable
We increment the value of the variable
Does skipping the third expression in the for loop save significant time?
It does not save anything at all
Also, the author of the MDN article seemed to like the second way of writing the loop - is there a reason that way is better?
It's not better in any way. Author just thinks it's cool and author likes to be cool (while they are not).
A for loop is really just a shorthand way of writing a while loop.
e.g. this loop
for(var i = 0, j = 10; i < 10; i++, j++) {
alert(i + ", " + j);
}
is just a shorter way of writing
var i = 0, j = 10;
while(i < 10) {
alert(i + ", " + j);
i++; j++;
}
So that mans this loop
for(var j=0, fruit; fruit = a[j++];) {
alert(fruit);
}
is the same as this
var j = 0, fruit;
while(fruit = a[j++]) {
alert(fruit);
}
You can follow through the order of execution of JavaScript's for loop using SlowmoJS: http://toolness.github.io/slowmo-js/
The homepage already has the for loop loaded into the console for demonstration purposes, but you evaluate the order of operation of any code, as you see fit.
I am working on a refactor of some older js and came across this loop:
var components = str.split('.');
var previousComponent = global;
for (var i = 0, component; component = components[i]; i++) {
if (typeof previousComponent[component] === "undefined") {
previousComponent[component] = {};
}
previousComponent = previousComponent[component];
}
I do not see how the guard statement says that this look ends. Could someone please explain this to me?
The condition component = components[i] "returns" component. It is undefined when i == components.length, therefore ending the loop.
As Jim Cote mentioned, another condition is if str has 2 dots together, then component can be an empty string, and also end the loop.
If your question is about when the loop ends, it ends when i is equal to the length of the array.
The condition part of your for statement is component = components[i] which assigns the value in components[i] to component and then returns that value to calling context - which is your for loop.
At the end of the array, when i === components.length, components[i] will be undefined which is not truthy, and hence breaks the loop.
In the for loop itself:
for (var i = 0, component; component = components[i]; i++) {
Note the part that says component = components[i].
This is not the equality comparison that we would typically find here, because it is =, not == or ===.
When the RHS (components[i]) is falsy, the loop will break.
My understanding is that the contents of a while loop executes while the condition is true. While working off of an example from an awesome O'Riely book, I've come across this implementation of the while loop...
window.onload = function(){
var next, previous, rewind; // globals
(function(){
// Set private variables
var index = -1;
var data = ['eeny', 'meeny', 'miney', 'moe'];
var count = data.length;
next = function(){
if (index < count) {
index ++;
};
return data[index];
};
previous = function(){
if (index <= count){
index --;
}
return data[index];
};
rewind = function(){
index = -1;
};
})();
// console.log results of while loop calling next()...
var a;
rewind();
while(a = next()){
// do something here
console.log(a);
}
}
I guess I'm wondering why, in this code, the while loop is not resolving to true infinitely? The function, next() isn't returning false after var index stops incrementing (++), is it? Shouldn't the console just be outputting eeny, meeny, miney, moe, moe, moe, moe.....etc...
I know this has probably been asked in some form, but have done searching and can't find a question or answer that explains using while (a = function()) {// do something} and how this loop is stopping after one pass through the array.
About why while (a = next()) {/*do something*/} doesn't repeat infinitely, it's about being coerced to false that counts - arguments are converted to booleans before being tested by the while loop. Things that coerce to false include 0, -0, undefined, null, "", NaN, and of course false itself.
When you assign something, it returns the value of the assignment itself. For example, if you do something like this:
var a;
console.log(a = '1234567890abcdefghijklmnopqrstuvwxyz');
It will log 1234567890abcdefghijklmnopqrstuvwxyz.
When the next performs index++, this increments the counter for the element index in the data array. This means that it will look for the next element in the data array every time you run the next() function - if there are no more elements, it will return undefined and therefore end the loop.
For example, see this:
var index = 0;
data = ['a','b','c'];
data[index]; // 'a'
index++;
data[index]; // 'b'
index++;
data[index]; // 'c'
index++;
data[index]; // undefined - if passed this will coerce to false and end the loop
Boolean(data[index]); // false
if (index < count) {
index ++;
};
When index is count - 1, this will still change index to count, right? And count is data.length. So, it then does this:
return data[index];
Which becomes
return data[data.length];
Since the length of an array is out of bounds of the array (they are zero-based), it will give undefined.
while(a = next()){
will become
while(a = undefined){
Since undefined is a falsy value, the loop will not be entered.
No,
It is not going to be an infinite loop. The while loop is basically going through the array and outputting it and when it is at the end of the array it just returns false and quits the loop.
This is something like;
foreach(a as nextArray)
{
//output
}
Hope this helps.