I've always defined the counter variable using var in my JavaScript for loops. I've recently realized that I am defining the same variable twice when I have multiple loops in a given script. Is there any problem with doing the following, or should I only define i once?
for (var i = 0; i < var1.length; i++){
//do something with var1[i]
}
for (var i = 0; i < var2.length; i++){
//do something with var2[i]
}
Your code will work (although could have unforeseen consequences) because of hoisting. Hoisting means that all declarations in a function are "hoisted" to the top during interpretation (which is fine because JavaScript has function scope anyway). Your code winds up being interpreted as:
function() {
var i;
for(i = 0; i < var1.length; i++) { }
for(i = 0; i < var1.length; i++) { }
}
So you can see that even though you think you declared i multiple times, both declarations are hoisted to the top and re-use the same variable.
As long as the two are used independently, you shouldn't technically have any issues. Unfortunately it makes your code less readable.
While declaring & initializing a variable in each for loop may give you a small overhead (with small I mean really small), I don't think that you should switch to declaring only once.
Declaring & initializing the counter variable in every for-loop separately is much more easily to read / handle and far more error-proof (what if you forget to reset the counter variable after a for loop?).
A variable should only be defined once in its scope, unless available in the lexical scope. For your example, you should be doing:
var i;
for (i = 0; i < var1.length; i++){
//...
}
for (i = 0; i < var1.length; i++){
// ...
}
This doesn't prevent changes to that variable however.
If I do:
var i = 0;
function A () {
i = 1;
}
A();
This will change i to 1. You're not redefining it, but passing it about and changing its value. This of course is a very simple example.
Variables are only contained within the statement. The only time you would have to worry about multiple variables are in either nested statements or re-declaring predeclared variables.
Related
For example:
is
for(var i = 1; i<100; i++){
var inc = 1/i*PI;
//and so forth
}
in any way better or worse than
var inc = 1/1*PI;
for(var i = 1; i<100; i++){
inc = 1/i*PI;
}
Of course the first is easier to type, but maybe it takes away speed/performance (even if a little bit) from the program when constantly re-declaring the same variable versus reassigning values to a global variable. Thank you.
Because of var hoisting, there is absolutely no difference between the two. And since it makes no difference, according to the docs:
For that reason, it is recommended to always declare variables at the top of their scope (the top of global code and the top of function code) so it's clear which variables are function scoped (local) and which are resolved on the scope chain.
Now if you were using let instead of var, the story would be different. I don't think there would be any performance difference at all, but there would certainly then be a semantic difference. The documentation for let goes into detail about those differences.
The second approach is correct. You should only declare variables once.
I would code your example like so:
var i,inc = 1/1*PI;
for(i = 1; i<100; i++){
inc = 1/i*PI;
}
This puts all the variable declarations in one place which makes it easier to read the code.
If you would like to use block level scope, use the let statement, like so:
var i;
for(i = 1; i<100; i++){
let inc = 1/i*PI;
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
I recently started using PHP Storm (love it) and noticed that it flags declarations of "var i" in for loops as duplicate in JavaScript. I learned that apparently the scope of that variable exists outside of the loop.
for (var i = 0; i < 10; i++) {
// Do anything
}
console.log(i); // i == 10
When I do my next for loop, should I declare var i again? Or, should I just say i = 0? I know I can do either, but one seems like bad style, the other like bad implementation.
On one hand, you shouldn't re-declare a variable that's in scope, but if I, for instance, delete the first for loop that declares "i", then everything else will break.
JavaScript has only function level scope, no block level scope. So, if a variable is declared anywhere within a function, it will be available for the entire function. So, you don't have to declare it again.
The best practice is to declare all the variables used in the function at the beginning of the function.
For example,
function myFunction() {
console.log(i);
for (var i = 0; i < 10; i++);
console.log(i);
}
myFunction();
Would print,
undefined
10
i is declared in the function, but till the for loop is executed, i is not assigned any value. So, it will have the default value undefined in it.
you need not declare it again. you can simply reassign the value of i for the next loop like
for (i = 0; i < 5; i++)
{
// Do anything
}
I see two differents way for declaring variables when making a "for loop" in javascript:
First way:
for (var i = 0, l = [].length; i < l; i += 1) {
// make something
}
Second way:
var i;
var l;
for (i = 0, l = [].length; i < l; i += 1) {
// make something
}
Is there some reason to prefer one of these?
They are same, you can use either BUT first is more readable and terse.
The point is that variables in both cases are local with the presence of var keyword. With first method also, you create two local variables:
var i, l
Instead of
var i
var l
Why use var keyword again and again when only one can do it. In fact that turns out to be one of the good practices of JS.
Given the code you show, they are the same thing. However, JS has some oddities which could cause issues in more complex code. Also, there is a question of maintainability and readability for future devs. Some of it is very subjective, some of it is objective.
I use a combination of the two, with slight variation--single var statement, top of scope.
var x = function () {
var i,
l;
for (i = 0, l = [].length; i < l; i += 1) {
// make something
}
};
The reason being that I prefer a single var statement per scope (function), and that statement to be at the top of the scope. JSLint/JSHint enforce this by default. Objectively, it helps avoid issues with the JS hoisting mechanism, which moves all variable declarations to the top of scope during the pre-execution pass. Admittedly subjectively, it makes very clear to later developers which variables are introduced in this scope. Any other var in use in the scope is assumed to be coming from a higher-level scope.
In javascript there is no difference except from a maintainability point of view. keeping declarations and usage close by helps in better readability. You should choose which ever is more readable.
No, both those are correct. I prefer the first myself.
An incorrect way is:
for (var i = l = 0; ...; ...) {
...
}
Where there is no comma between i and l wich causes l to be global.
No, at least in Chrome the scope is exactly the same and both ways are equivalent.
actually according to the almighty crockford there is: because javascript has function scope it is preferred to always declare variables first thing in the head of the function.
However, as others have pointed out, it doesnt really matter and should be done according to personal taste and readability.
The reason why one would prefer the second over the first is that variables in JS don't have block scope, but instead lexical (or function) scope, which means that variable are visible within the function they are defined (they are also visible in nested functions).
Example:
function foo() {
for (var i = 0; i < 10; i++) {
alert(i);
}
alert(i); // works, because i has lexical scope
}
In most C-like languages, variables have block scope, which means they are visible within the block where they are defined, so:
void foo() {
for (int i = 0; i < 10; i++) {
print(i);
}
}
print(i); // won't work, i is not visible any more
So, people coming from languages like Java/C/C++ may think that var i in the first example has block scope, where it actually has not. This is why some programmers prefer declaring all variables at the beginning of functions.
Personally I think even then you should stick to the habit to declare variables as close as possible to where they are used.
EDIT
As JAAulde mentioned, you should only declare variables close to their usage if you've really understood JS scoping rules (and quirks).
Perhaps I'm not aware of how for loop index variables get scoped, but I was very surprised when one of my loops didn't complete, seemingly because a function called from within a loop contained an i for its for loop index as well.
Here's a little script I put together to demonstrate this behavior:
var loopOne = function(test) {
for(i = 0; i < test.length; i++)
console.log(getMask(test));
};
var getMask = function(pass) {
var s = "";
for (i = 0; i < pass.length; i++) {
s = s + "*";
}
return s;
};
loopOne('hello');
If I run this in Chrome and look at the console log, I should see ***** five times. However, I only see it once. Upon further inspection, if I type i in the Chrome javascript console, it will output 6 ( = 'hello'.length + 1). This makes me think that i has become a part of the global scope and is not limited to the scope of the for loop for which it was needed.
Is this correct? If so, what's a better practice for defining the index variable of a for loop in javascript?
In Javascript, variables are scoped with the var keyword. When declaring variables with var, the variable is scoped to the current function. When assigning to a variable without using the var keyword, it is assumed you're talking about an already defined variable in the same or a higher scope. If none is found, the variable is created in the highest scope.
Bottom line: declare all your variables using var.
You should declare your loop index variable with let:
for (let i = 0; i < test.length; i++) ...
That will declare and set the proper scope for the variable.
When you declare your variables with var, you scope them to the current execution context.
When you don't, they become properties of the global object (window in a browser).
If I have a pair of functions that both set local variables, for example, the variable i in common for loops, and one happens to be called while the other is running, is there any danger of namespace confusion?
Keep in mind that JavaScript does not have block scope, but only function scope.
In addition, if you have nested loops, there will only be one i variable in the following example:
function myFunction() {
for (var i = 0; i < 10; i++) {
for (var i = 0; i < 10; i++) {
// code here will run 10 times instead of 100 times
}
}
// variable i is still accessible from here
}
Douglas Crockford recommends that the var statements should be the first statements in the function body in Code Conventions for the JavaScript Programming Language:
JavaScript does not have block scope, so defining variables in blocks can confuse programmers who are experienced with other C family languages. Define all variables at the top of the function.
I think he has a point, as you can see in the following example, which will not confuse readers into thinking that the variables i and j are held in the scope of the for loop blocks:
function myFunction() {
var i, j; // the scope of the variables is now very clear
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// code here will run 100 times
}
}
}
As long as you're using var, like this:
for(var i = 0; i < something; i++)
Then it's local and you're fine, if you don't use var, you have a global variable on your hands, and potential issues. Also if a for loop is nested in another, you should use a different variable name for each loop.
It will be a problem if are you referring to nested loops. Every time you enter the second for loop, the value of i (previously set in the outer for loop) will be reset.