12

It totaly makes sense to me to use it here. What would be the alternative? How can i generaly avoid to use them and most of all why is it bad according to jsLint to make use of globals.

(function($){
  $(function(){
   $body = $('body'); //this is the BAD Global

   $.each(somearray ,function(){ $body.dosomething() });

   if (something){
     $body.somethingelse();
   }

  });
}(jQuery));

Can you help me understand this? And give me a better solution?

meo
  • 30,872
  • 17
  • 87
  • 123

5 Answers5

19

Globals are bad because they don't cause problems right away. Only later, after you have used them all over the place, they will cause very ugly problems - which you can't solve anymore without writing your code from scratch.

Example: You use $body to define some functions. That works fine. But eventually, you also need a value. So you use $body.foo. Works fine. Then you add $body.bar. And then, weeks later, you need another value so you add $body.bar.

You test the code and it seems to work. But in fact, you have "added" the same variable twice. This is no problem because JavaScript doesn't understand the concept of "create a new variable once." It just knows "create unless it already exists." So you use your code and eventually, one function will modify $body.bar breaking another function. Even to find the problem will take you a lot of time.

That's why it is better to make sure that variables can only been seen on an as needed basis. This way, one function can't break another. This becomes more important as your code grows.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
2

you should define it with var $body, then it would be local in the scope of that function, without var it could be overwritten by everybody

(function($){
  $(function(){
   var $body = $('body'); //this is the local variable

   $.each(somearray ,function(){ $body.dosomething() });

   if (something){
     $body.somethingelse();
   }

  });
}(jQuery));
mpapis
  • 52,729
  • 14
  • 121
  • 158
  • Or overwrite some 'other' global variable called $body – Mchl Nov 22 '10 at 14:22
  • yes, but in this example it would replace the global value, this way it only hides it in scope of the function – mpapis Nov 22 '10 at 14:24
  • 2
    A function literal using local variables that were declared in the same scope as the function was defined is called a [closure](http://jibbering.com/faq/notes/closures/), and should be used extensively in jQuery to great effect. – Phrogz Nov 22 '10 at 14:27
2

Globale variables could clash with other Scripts or be overwritten. When you don't need a global, it's advisable to avoid them. Simply use var (or let if your JS-Version-Support is greater than 1.7):

(function() {
  var foo = 'bar';
  alert(foo);
})();
pex
  • 7,351
  • 4
  • 32
  • 41
2

You could rewrite that as

var $body = $('body');

That (the use of the var keyword) would make it a local variable, which is enough for your purposes. It will still be within scope in your each callback.

The reason it's bad to use globals is that it can be overwritten by anything else. For your code to scale well, it becomes dependent on what other scripts you use. It's preferable to keep the script as self-sufficient as possible, with as little as possible dependencies pointing to the world outside of it.

David Hedlund
  • 128,221
  • 31
  • 203
  • 222
0

jsLint is very stringent. It's probably not necessary to get too hung up about it.

But if you feel bad, you can do it just like how you scoped jQuery:

(function($){
  $(function(){
   $.each(somearray ,(function($body){ $body.dosomething() })($('body'));

   if (something){
     $('body').somethingelse();
   }

  });
}(jQuery));
kizzx2
  • 18,775
  • 14
  • 76
  • 83
  • 3
    I agree that it isn't generally necessary to get all worked up on everything jsLint says, but I wouldn't mention that in this context, because I really agree that if globals can be painlessly avoided, they should be, and in this code the variable can be declared as a local variable, and no other action is required. – David Hedlund Nov 22 '10 at 14:26