JavaScript: Is window.spam a good practice?
I've noticed all over the place people mention "Just define a variable in the top of your JS code and it becomes global" in response to questions like, "How do I create a global variable from inside a function?". Most of the answers start by saying it isn't possible to achieve that. Of course it is possible to do this:
<script type="text/javascript">
window.spam = 'Hello World';
</script>
Then, later in your code, you can say:
<script type="text/javascript">
alert(spam);
</script>
This works perfectly fine in IE6+, Firefox, Chrome, Safari, etc. So why does nobody do this?
In my case I want people to access a global variable called fooBar
from anywhere in their code and in my AJAX library, I want the variable to update behind the scenes automatically so that when they say $.do_some_magic()
they can be sure that fooBar
will reflect the changes made by $.do_some_magic()
without having to think about it. I don't want them to have to create the variable up high in their code and I don't want to create the variable up high in my library code either. I suppose I just hate defining global variabl开发者_StackOverflow中文版es at the top and would rather not unless there is a good reason not to. Is there?
Clarity
Its an explicit way of showing that you meant to create a global variable.
// Unclear: Intentional, or accident
function privateScope() {
spam = "hello";
function globalFunction() {
}
}
That will make a variable global simply because it was declared that way, though it is not immediately obvious the programmer intended the variable and the function to have a global scope.
// Clear: Intentional global use
function privateScope() {
window.spam = "hello";
window.globalFunction = function () {
}
}
This example is more obvious.
Best Practice
If you know ahead of time a variable will be used with the global scope, it should be declared at the top of your file, outside all your functions:
var spam;
If you are inside a self executing anonymous function, then explicitly use window.spam
:
(function(){
// currently private to this scope
var spam;
... lots of code ...
// Expose the variable publically
window.spam = spam;
})();
Name Collision
anthares brought up the other side of this, which is name collision
A number of libraries expose a single top level object. You could either construct a function to do this, or use a simple object literal as a namespace:
(function(){
// Expose a single top level variable
window.YourCompany = { };
// Private:
var spam = "name";
... other code ...
// Make public
window.YourCompany.spam = spam;
})();
Sure, you can say window.spam
. But you would only need to if you had also defined a local variable called spam
. Otherwise just saying spam
automatically refers to the global variable.
It's bad practice to refer to a global variable you haven't declared with var
, but it'll work unless you use ECMAScript Fifth Edition ‘strict mode’.
Because var
declarations are ‘hoisted’ and processed before code, there is no reason you have to define your globals “at the top”. This is perfectly valid even in strict mode:
function setFooTo6() {
fooBar= 6;
}
var fooBar;
although I'd hesitate to do that as it's not entirely clear.
精彩评论