HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Clarification on jQuery global variables in external files and scope

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
globalclarificationscopejqueryfilesvariablesandexternal

Problem

Now that I've used it a lot, I think I'm starting to get the hang of jQuery and its capabilities. One thing I'm still unclear about is how global variables are initiated and used, and when the variable is in reference to a jQuery object, both cases especially in and with external JavaScript files.

For example, if we had this test website:

HTML file


  
    
    
    
      .header {
        color: orange;
        background: blue;
        font-size: 1.5em;
      }
      .content {
        color: purple;
        background: pink;
      }
      h1, h2 {
        position: relative;
        margin: 0 auto;
      }
    

    
    
    
      // Global undefined variable. Is this allowed?
      window.globalUndefined;
      // Global variable referencing a number?
      window.globalNumber = 42;
      // Global undefined jQuery object?
      window.$someElement;
      // Global jQuery object. Do I need window. in front of the right-hand statement?
      window.$allP = $("p");

      $(document).ready(function() {
        // Using global variable in document
        $allP.click(function() {
          $(this).css("color", "red");
        });

        // Using global variable from external file internally. Is this correct?
        $allHeaders.click(function() {
          $(this).css("color", "green");
        });

        // Am I passing these correctly?
        doSomething($allP, $allHeaders);
      });
    
  
  
    
      
        EXAMPLE PAGE
        hi guys lol
      
    
    
      
        Paragraph 1
        Lorem ipsum
      
    
  


And then, our two relevant external files:

external.css

body {
  background-color: light-blue;
  font-family: sans-serif;
  width: 100%;
}
.wrap {
  width: 50%;
  border: 2px solid black;
}


example.js

```
// Does an external jQuery file need $(document).ready wrappers around it?
// Global undefined variable. Is this allowed?
window.extGlobalVar;
//Global variable referencing a number?
window.extGlobalNumber =

Solution

Let me first try to clear up what I expect to be some confusion:

All JavaScript code on a page runs in the same environment. Whether a piece of code is defined in an external file or in the page itself makes little difference, as long as things are loaded in the proper order.

So if you had HTML like


  /* chunk of code 1 */
  /* chunk of code 2 */
  /* chunk of code 2 */


It's the same as:

 /* chunk of code 1 */ 
 /* chunk of code 2 */ 
 /* chunk of code 3 */ 


Which, in turn is the same as:



From the browser's point of view, all JS - whether part of the HTML or in a separate file - is just part of one big JS file. So in you case, that file starts with all of jQuery's code, then the code from "example.js" and then the code in the HTML.

So when you say "externally-held" and "internally-held", I say "same difference". Functions, where ever they're defined, have their own internal scope (and access to any "outer" scope) - files do not automatically constitute a scope.

To answer your questions directly:


In the above examples, am I using the various global variables and global jQuery objects correctly (in both the internal and external cases)?

Yes and no. Yes in the sense that you're doing it right, but no in the sense that you may not be doing the right thing :)

Global variables are useful ($ aka jQuery is a global variable), but the fewer you have, the better. JavaScript is the wild west: Browsers and libraries may define different things in the global scope, so it's easy to step on something's toes - or have your own toes stepped on, if some library accidentally overwrites your global variables.

So the usual guideline for JavaScript is to avoid "polluting the global scope". Hence why jQuery "hides" (almost) all its functionality behind the $ variable: It limits jQuery's footprint to a single variable (even so, there were libraries before jQuery that used the global $ for something, so things can still get weird).

So, again, yes, those are global variables, and - since everything is essentially one big file - you're doing that part right. But even so, I wouldn't recommend it.


In the above examples, am I passing the two global variables into that (externally-held) jQuery function correctly (in both the internal and external cases)?

Again: Yes and no. It certainly makes sense to pass them - but it's not necessary to make them global to begin with.


Am I calling that (externally-held) jQuery function correctly?

Sure - again: One great big file.


Is there a way to be able to call an externally-held jQuery function on an object internally? E.g. $("div").doSomething(), but doSomething is defined in an external file. If so, how?

Yes: Plugins. Plugins are how you extend jQuery with custom functionality. It's slightly more involved than just writing a function, but it's not too bad.

Still, consider if it's worth it. The functionality you're adding should be somewhat generic to really make sense. For instance, jQuery UI defines a bunch of plugins to animate elements and such. This works for any element, on any page. The same way jQuery itself makes sense on any page, anywhere.

But if your functionality is more specific (i.e. only works in your specific circumstances) don't bother with plugins. Functions work just fine too. Sure, it may not be quite as neat as writing $("div").doSomething(), but it's a lot more flexible. You can define tons of plugins, but.. eh', not worth it.

In your case, your doSomething function relies on global variables, and its functionality is very specific (in other words, it's tightly coupled to your circumstances), so making it a plugin would be complicating matters.

Still, as an example, here's a plugin that makes the background of an element red (that is, a fairly generic - if useless - piece of functionality that doesn't rely on a specific context):

jQuery.fn.paintItRed = function () {
  this.each(function () {
    $(this).css('background', 'red');
  });
  return this;
};


You can then use $("div").paintItRed(), and it'll make all the DIVs red! Yay?


If we're allowed to have undefined global variables, can I later set them in the external file, or do they have to be set internally? Or can I do either?

Well, undefined means just that: Not defined. At all. So if you do nothing at all, the variable will be undefined. it also means that doing this:

window.anUndefinedVariable;


doesn't do anything really. You're not really declaring anything (at best, JavaScript will attempt to read the variable, which isn't defined).

And again, we're back to why global scope pollution is a problem: Any piece of code can define or overwrite a global variable. So for instance, jQuery defines $ as a global variable, but your code can easily re-define it as null - and then you can't use $ for anything.


Can you declare global variables in a function or in the $(document).ready() wrapper if you format it as wi

Code Snippets

<script>
  /* chunk of code 1 */
  /* chunk of code 2 */
  /* chunk of code 2 */
</script>
<script> /* chunk of code 1 */ </script>
<script> /* chunk of code 2 */ </script>
<script> /* chunk of code 3 */ </script>
<script src="chunk1.js"></script>
<script src="chunk2.js"></script>
<script src="chunk3.js"></script>
jQuery.fn.paintItRed = function () {
  this.each(function () {
    $(this).css('background', 'red');
  });
  return this;
};
window.anUndefinedVariable;

Context

StackExchange Code Review Q#69777, answer score: 3

Revisions (0)

No revisions yet.