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)
Answer from bobince on Stack OverflowBest way to declare variables
performance - JavaScript variables declare outside or inside loop? - Stack Overflow
coding style - Where to declare a variable and define a function in Javascript? - Software Engineering Stack Exchange
Javascript best practices: where to declare variables
Videos
I’ve heard that when declaring variables, you want to use let unless yk it will never never and you use const instead. However, I just heard the opposite where you always use const unless yk it’s going to change and then you use let. I am only asking because I have definitely seen come const where I would’ve used a let.
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)
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++) {
// ...
}
}
My question is, where do I declare the
bazvariable?
So the generic answer to this question is "wherever you want", but of course that's not helpful and has pitfalls, so I'm going to tell you where I recommend putting it, and attempt to defend my logic as best as possible.
No matter where you declare a function* or variable** in JavaScript, the function or variable will be hoisted to the top of its containing scope***. If there is no containing scope, it will be implicitly added to the global namespace (in browsers this is window, in NodeJS this is global).
When a variable or function is hoisted, it means that the JavaScript interpreter will pretend as though your variable declaration were written as the first line of the containing scope.
In practice what this means is that when you write:
(function () {
...a...
if (...b...) {
var example = ...c...;
// ^^^^^^^^^^^
}
}());
It's actually evaluated as:
(function () {
var example;
//^^^^^^^^^^^
...a...
if (...b...) {
example = ...c...;
}
}());
* I'm referring to function declaration here. I.E. function name(...) {...}
** I'm referring to variable declaration with var here. I.E. var name
*** Containing scope is typically the wrapping function, but sometimes for various reasons there is no wrapping function.
Isn't it safer to code as follows, where
varis used where the variable is first used?
Because of hoisting this classic best practice becomes susceptible to simple mistakes.
Consider the case where you write some code...
(function () {
for (var i = 0; i < x.length; i++) {
...do stuff...
if (...something happens...) {
break;
}
}
...more stuff...
...even more stuff...
doSomethingWith(i);
}());
Then you come back later, and need to add some new functionality, so you add:
...more stuff...
for (var i = 0; i < y.length; i++) {
...do stuff...
}
...even more stuff...
Now, if you combine the two it's easy to see in this contrived example that sloppiness has led to accidentally redeclaring and overriding the i variable.
This might seem silly, but it happens all the time. It's quite easy if you don't actively take steps to avoid it. This sort of an issue isn't a problem in languages with block scope, because i would be contained in each for loop's scope, and to use doSomethingWith, we would have had to expose the value of i to the parent scope.
With that all said, your question is really one of best practices. This is inherently subjective and will lead to disagreement. I'm going to post my opinion and I will attempt to defend it, but it should be treated as an opinion and not dogma.
In my opinion, functions should have the following flow:
- Directives
- Variable declaration
- Function declaration
- Variable instantiation
- Other code
(1) Directives are things like "use strict". They come first by definition.
(2) Variable declaration using var comes second. They could come after function declaration, or even in between, but I've found it makes them harder to find. I also recommend using exactly one var statement with each var placed on separate lines, organized alphabetically. This forces variables to be clustered together, and alphabetical ordering prevents accidental duplication.
(3) Function declaration comes next because functions are hoisted just like variables. Seeing what local APIs are available within a given scope is something I find useful.
(4) Variable instantiation comes after function declaration, and in my opinion should be separate from declaration. Yes there are circumstances where it's easier to just put them on the same line, but as a general rule, you can't go wrong with keeping them separate.
The reasoning for this one is two-fold.
First, the declaration will be interpreted to happen before the assignment, so writing code that reads the way the interpreter is going to interpret it will help with understanding.
Second, if the assignment is merged with the declaration, order suddenly starts to matter, and you lose the ability to consistently alphabetize your variables.
As an example:
(function () {
var x = ...x...,
y = ...y...,
length = Math.sqrt(x * x + y * y);
// ^^^^^^ no longer alphabetical
}());
If you separate the declaration from assignment, you can get the benefits of both:
(function () {
var length,
x,
y;
x = ...x...;
y = ...y...;
length = Math.sqrt(x * x + y * y);
}());
(5) Once you're done with all the setup for a function, you'll need to write the rest of the code. This step is the "rest of the code" step.
If you've been paying attention to ECMAScript2015, then you should know that there are two new ways to declare variables: let and const.
These new variable declarations use block scope. If you're assigning a variable that will never be overwritten, use const, otherwise use let.
Going back to:
Isn't it safer to code as follows, where
varis used where the variable is first used?
let allows you to do this. If you can use let, stop using var; use let and const where the variables are first used; combine declaration with assignment:
ES5 way:
(function () {
var example;
...
example = ...;
}());
ES2015 way:
(function () {
...
let example = ...;
}());
Javascript variables only have 2 scopes, global and local. A variable declared inside a function (inside an IF or not) is accessible to the whole function.
Personally I declare variables toward the top of a function for the sake of clarity, and with the above in mind. Therefore I am in agreement with the advice given in your book.
You may want to look into "let" and "const", part of ECMAScript 2015 (ES6).