js: var declarations, loops, efficiency, utility
readability aside ... in terms of efficiency and/or functionality, i'm not clear on the difference between placing a declaration outside (my practice) or inside a loop (seen in other SO posts). or for that matter, why code declarations at all? here are some degenerate examples ... more comments below.
A1:
var x;
for (i=0; i<10; i++){
x = i;
}
A2:
for (i=0; i<10; i++){
var x = i;
}
B1:
var i;
for (i=0; i<10; i++){
}
B2:
for (var i=0; i<10; i++){
}
C1:
var x;
var y;
C2:
var x, y;
readability aside ... i suspect that there is no difference between B1 & B2 and between C1 & C2, but am leery of an efficiency or functional difference between A1 & A2. also, i am not sure what advantages exist for declarations at all except for using declarations in functions to eliminate(?) possible conflict with a globa开发者_Go百科l variable of the same name.
EDIT: added a couple semicolons
EDIT: 1st sentence clarity, changed function to functionality
EDIT: adding some code below to aid in a comment below that i made EDIT: comments
<!doctype html>
<html>
<head>
<script type='text/javascript'>
var w = (function(){ // wrapper
alert('init');
function p(){ // private
alert('p');
w.b(); //needs prefix
}
return{
a: function(){ // public
alert('a');
p();
w.b(); // needs prefix
},
b: function(){ // public
alert('b');
}
};
})(); // execute immediately
</script>
<script type="text/javascript">window.onload=w.a;</script>
</head>
<body>
sequence of alerts will be 'init' 'a' 'p' 'b'
</body>
</html>
Variable declarations get hoisted up to the top of the function. It won't make any difference, unless of course you're talking about declaring a variable in a new function scope.
EDIT: Didn't notice at first, your first example didn't declare i
with var
. That's not good practice.
EDIT:
Generally it is a good idea to avoid creating global variables in order to avoid conflicts with other scripts that may be setting globals.
Whenever you use a variable without declaring it with var
, it becomes global.
The only way a new variable scope is created in JavaScript is in the body of a function. Functions can be nested inside each other, creating a scope chain that begins with the innermost function, and ends with the global scope.
Because of this, it is common to place all your code in a function that is invoked immediately. That way any variables you create with var
won't end up as globals.
(function() { // <-- create a function
// place your code in here
// use "var" when declaring variables so they don't become global
var name = "patrick dw";
alert( name );
})(); // <-- invoke the function immediately so your code runs
In the preceding example, the name
variable will be local to the immediately invoked function, and won't pollute the global scope.
Because traversing the variable scope takes some resources, it is common for people to invoke that function with some arguments being passed in, like window
.
(function( window, undefined ) {
// now the window object is referenced locally. Better for performance.
var name = "patrick dw";
alert( name );
})( window ); // <-- invoke the function passing in the global "window" object
Now the window
object is referenced locally inside your function, so if you access some property of window
, it won't have to follow the scope chain all the way outside your function.
I also included an extra undefined
parameter in the function, but didn't pass an argument to it. This is to help avoid an odd issue brought about by some bad coding practices. But that's another issue.
Now taking that same function, if we didn't use var
in declaring our name
variable, it would automatically have become global. I'll update the example, and I'll add another function scope to illustrate.
(function( window, undefined ) {
// create a function
function some_func() {
name = "patrick dw"; // didn't use "var" when declaring!!
alert( name );
}
some_func(); // call our function
alert( window.name ); // but "name" is also accessible from the global window
})( window );
alert( name ); // outside those functions, we're global, and again we can see that
// the "name" variable is accessible
So as you can see, we never declared var name
, so it became an automatic global variable even though it was nested two functions deep.
This is the source of many errors, and is the reason you need to be extra careful to use var
.
Finally, I'd note that ECMAScript 5 disallows some bad coding practices when you run your code in "strict mode";
. Not many browsers implement strict mode
right now, but would be helpful to test your code every so often in one that does.
Here's a compatibility table for ECMAScript 5. Strict mode is at the bottom. You'll see that Firefox 4 supports it.
Here's an example:
(function( window, undefined ) {
"strict mode"; // <-- use the strict mode directive
name = "patrick dw"; // In Firefox 4, you should get a ReferenceError in the console
// because "name" was never declared with "var"
})( window );
its all just syntax differences. I think even at B both declarations are in the same scope.
just declaring i without var will cause it to be defined in global scope.
It's mainly about what option fits situation best, while it should still be kept as consistent as possible.
If you already have a global variable x, I don't think any of this would prevent a collision.
The scope of a javascript variable is shared with the entire function when using var
, so there won't be any difference between A1 and A2 when those are both in a function.
You can however use the let
keyword and restrict that variables scope to a block, for instance:
for(let x = 0; x < 10; x++){}
That will restrict the x
variable to only have scope within the for{} block.
There is no functional or efficiency difference between A1 or A2 either. Try this:
var arr=[];
for(var i=0; i<10; ++i) {
var x=i;
arr.push( function() {alert(x);} );
}
for(var i=0; i<10; ++i) {
arr[i]();
}
You'll see that the value shown by all functions is same, because its the same x that all the functions use. New variable is not created each time.
精彩评论