In AS3 I believe you should initialise all variables outside loops for increased performance. Is this the case with JavaScript as well? Which is better / faster / best-practice?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
or
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
-
8Outside! always outside.BGerrissen– BGerrissen2010年09月10日 13:27:39 +00:00Commented Sep 10, 2010 at 13:27
-
39Hmm, don't variable declarations get pushed up to function scope anyway in both Javascript and AS3? If I'm correct, then it really doesn't matter.spender– spender2010年09月10日 13:29:51 +00:00Commented Sep 10, 2010 at 13:29
-
3@Andy - did you try assigning before declaring in a function body? Perhaps your preconceptions are leading you astray. WRT performance, with push-up scoping, if the JS is interpretted, then it will chew extra cycles within a loop block. If compiled (which most engines do nowdays) it won't matter.spender– spender2010年09月10日 13:38:10 +00:00Commented Sep 10, 2010 at 13:38
-
2Great question! Thanks. After reading all the answers, I believe if its just a small loop or only a temp variable I will keep them where they are needed and it doesn't effect performance. If a var is used within a function more than once, why not refer to it inside the function and finally globals then can be sat outside the fn()Dean Meehan– Dean Meehan2014年02月26日 11:30:30 +00:00Commented Feb 26, 2014 at 11:30
-
3I'm surprised no one tried to measure performance. I created a jsperf. Seems to be a little faster when declared inside the loop for Safari and Firefox, the opposite for Chrome...Buzut– Buzut2014年10月01日 17:57:26 +00:00Commented Oct 1, 2014 at 17:57
13 Answers 13
There is absolutely no difference in meaning or performance, in JavaScript or ActionScript.
var is a directive for the parser, and not a command executed at run-time. If a particular identifier has been declared var once or more anywhere in a function body(*), then all use of that identifier in the block will be referring to the local variable. It makes no difference whether value is declared to be var inside the loop, outside the loop, or both.
Consequently you should write whichever you find most readable. I disagree with Crockford that putting all the vars at the top of a function is always the best thing. For the case where a variable is used temporarily in a section of code, it's better to declare var in that section, so the section stands alone and can be copy-pasted. Otherwise, copy-paste a few lines of code to a new function during refactoring, without separately picking out and moving the associated var, and you've got yourself an accidental global.
In particular:
for (var i; i<100; i++)
do something;
for (var i; i<100; i++)
do something else;
Crockford will recommend you remove the second var (or remove both vars and do var i; above), and jslint will whinge at you for this. But IMO it's more maintainable to keep both vars, keeping all the related code together, instead of having an extra, easily-forgotten bit of code at the top of the function.
Personally I tend to declare as var the first assignment of a variable in an independent section of code, whether or not there's another separate usage of the same variable name in some other part of the same function. For me, having to declare var at all is an undesirable JS wart (it would have been better to have variables default to local); I don't see it as my duty to duplicate the limitations of [an old revision of] ANSI C in JavaScript as well.
(*: other than in nested function bodies)
18 Comments
var is only used at the top of a function is just asking for accidental global variable creation. And having a mass of unrelated variables all declared in one spot is semantically meaningless, especially when some of those variables may end up never being used.In theory it shouldn't make any difference in JavaScript, since the language does not have block scope, but only function scope.
I'm not sure about the performance argument, but Douglas Crockford still recommends that the var statements should be the first statements in the function body. Quoting from 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. Declaring the variables at the top of the function should not confuse readers into thinking that the variable i is held in the scope of the for loop block:
function myFunction() {
var i; // the scope of the variables is very clear
for (i = 0; i < 10; i++) {
// ...
}
}
6 Comments
let affect this answer?The ECMA-/Javascript language hoists any variable which is declared anywhere to the top of a function. That is because this language does have function scope and does not have block scope like many other C-like languages.
That is also known as lexical scope.
If you declare something like
var foo = function(){
for(var i = 0; i < 10; i++){
}
};
This gets hoisted to:
var foo = function(){
var i;
for(i = 0; i < 10; i++){
}
}
So it does not make any difference in performance (But correct me if I'm totally wrong here).
A much better argument for not declaring a variable somewhere else than at the top of a function is readability. Declaring a variable within a for-loop might lead to the wrong assumption that this variable can only be accessed within the loop body, which is totally wrong. Infact you can access that variable anywhere within the current scope.
2 Comments
let affect this answer?Next year, all browsers will have JS engines that precompile the code so the performance difference (which comes from parsing the same block of code again and again plus executing the assignment) should become negligible.
Also, never optimize for performance unless you have to. Keeping variables close to the place where you need them the first time keeps your code clean. On the negative side, people who are used to languages with block scopes might be confused.
1 Comment
Another consideration, now that we have let and const in ES2015, is that you can now scope variables specifically to the loop block. So unless you will need the same variable outside the loop (or if each iteration depends on an operation done to that variable in the previous iteration), it's probably preferable to do this:
for (let i = 0; i < 100; i++) {
let value = somearray[i];
//do something with `value`
}
2 Comments
{ and } is its own scope; the let value is specific to that block (and I suppose to that specific iteration as well) and no longer exists on the next iterationI just did a simple test in Chrome. Try the fiddle in your browser and see the results
var count = 100000000;
var a = 0;
console.log(new Date());
for (var i=0; i<count; i++) {
a = a + 1
}
console.log(new Date());
var j;
for (j=0; j<count; j++) {
a = a + 1;
}
console.log(new Date());
var j;
for (j=0; j<count; j++) {
var x;
x = x + 1;
}
console.log(new Date());
Result is that the last test takes ~8 seconds and the previous 2 are only ~2 seconds. Very repeatably and regardless of order.
So, this proves to me, that one should always declare the vars outside of the loop. Curious case to me is the first one where I declare i in the for() statement. This one appears to be just as fast as the 2nd test where I pre-declare the index.
14 Comments
var is declaring as global a variable that would be global anyway.JavaScript is a language written at the bottom by C or C++, I'm not very sure which one it is. And one of its purpose is saving the lavour of handling internal memory. Even in C or C++, you won't have to worry about whether it will consume a lot of resources when variables are declared inside a loop. Why should you worry about it in JavaScript?
2 Comments
I prefer combining both readability and performance. So my favourite is to declare variable inside loop, that mean I would have block scope encapsulation.
for (let i = 0, sum = 0; i < count; i++) { // count also be declared here like count = array.length;
sum = sum + 1;
}
Based on previous provided fiddle performance tests the winner is number 4
Comments
Well, that depends on what you're trying to achieve... if value suppose to be only a temporary variable inside loop block then it's much clearer to use second form. It's also more logical and verbose.
1 Comment
It Doesn't make difference if you declare variables inside or outside of for loop. Below is the sample code to test.
function a() {
console.log('Function a() starts');
console.log(new Date());
var j;
for (j=0; j<100000000; j++) {
var x;
x = x + 1;
}
console.log(new Date());
console.log('Function a() Ends');
}
a()
function b() {
console.log('Function B() starts');
console.log(new Date());
var a;
var j;
for (j=0; j<100000000; j++) {
a = a + 1;
}
console.log(new Date());
console.log('Function B() Ends');
}
b()
The results showed in my case
Function a() starts
VM121:3 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:9 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:10 Function a() Ends
VM121:14 Function B() starts
VM121:15 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:21 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:22 Function B() Ends
Thank you -- MyFavs.in
The question here is basically to declare a var inside a loop. Just think what happens if you do this:
var a = 30;
var a = 50;
var a = 60;
Do you think this is right? No ... because you don't want to declare a variable so many times. When you declare a variable inside a loop isn't it declaring as many times the loop runs? Obviously it will slap you when you are in 'use strict' mode. People have disagreed with Crockford without thinking about the original question.
So it is always good to declare variables on top -- 1. For readability, 2. Making good habits.
1 Comment
After philosophizing on this for years, I am totally sold on declaring variables upon their first use, and not at the top of the function. This is the easiest, most readable, most logical and portable way of doing things. Knowing where in the function the variable was first used is important added information, and for large complex functions it can stop your brain from turning into oatmeal.
I hope for a paradigm shift, like how we ditched the semi-colon. I now want to vomit when I see semi-colons at the end of a line, and they are legacy now. I think the only place I use semi-colons is when I put TWO statements on ONE line, another acceptable approach that people think is a sin.
A general rule for new coders would be forget what people have told you and just make your code concise and readable. Avoid writing an essay of comments to explain how it works for other people, only do this for yourself. If you understand the code, you don't need any comments. You will likely start a function with some comments and remove them as the code settles. The best way to understand how a function works is to read the code, not the comments. Comments are best for explaining what isn't obvious.
1 Comment
In regards to performance after running test on Chrome, Firefox, and jsperf on a Linux OS there does appear to be a performance difference between the declaration of variables in a loop and out of a loop. It is a small difference but this is also compounded by the amount of iterations and the amount of variable declarations.
Therefore for best performance I would have to suggest declaring variables outside the loop. Or better yet declare your variables in line. See example.
// inline
for (var ai = 0, al = 100000000, av; ai < al; ai++) {
av = av + 1;
}
// outside
var bv;
var bl = 100000000;
for (var bi = 0; bi < bl; bi++) {
bv = bv + 1;
}
Notice how the variable 'al' and 'av' are in the for loop declaration line. This inline declaration has provided me with consistently better performance. Even over the declaration of variables outside the loop. Again the performance difference is really small.