Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does jQuery protect overwriting jQuery and $

These variables are located immediately after defining a local copy of jQuery in the jQuery source.

// Map over jQuery in case of overwrite
_jQuery = window.jQuery

// Map over the $ in case of overwrite
_$ = window.$

One can read the comments and know the why... but

  • How do these lines of code do this?

  • Would adding something similar protect my personal namespace or is there more too it deeper in the source?

  • What is an example of something bad that could happen if this weren't in the source code?

like image 263
Derek Adair Avatar asked Jan 21 '23 21:01

Derek Adair


2 Answers

If you look through the jquery.js file you will find that they start by saving the previous definition (line 31-32 v1.4.4):

// Map over the $ in case of overwrite
_$ = window.$,

Then if you call noConflict it just sets the value back (line 397-398)

noConflict: function( deep ) {
    window.$ = _$;

You can add something similar to your own project to protect the name space. The concept holds for more than just javascript.

If these lines were not included, then you wouldn't be able to run jQuery and Prototype on the same page as both use the $ operator - nothing bad may happen, it's just that your code won't work and possibly cause errors.

like image 194
Mottie Avatar answered Jan 27 '23 21:01

Mottie


How does jQuery protect overwriting jQuery and $

It doesn't (but see below). If you load jQuery, and then load something else that writes something else to those symbols, they won't be associated with jQuery anymore. Example:

HTML:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js"></script>

JavaScript:

window.onload = function() {
  // Outputs false, because Prototype has overwritten it
  display("Does $ === jQuery? " + ($ === jQuery));

  // Outputs true, because Prototype has overwritten it
  display("Does $('foo').id === 'foo'? " + ($('foo').id === 'foo'));

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
  }
};​

Live copy

But, it does seem to preserve them. How?

The answer is closures. It has a local reference, inside its scoping function, which is unconnected to the global reference (the property on window), so internally it doesn't care whether you overwrite those symbols. Of course, you care, if you overwrite both $ and jQuery, because if you do you have no way of calling jQuery. :-) But if you only overwrite $, that's not a problem, just use jQuery or if you don't like typing that (and let's face it, it's awkward), do this:

(function($) {
    // Your usual jQuery code here using `$`,
    // this code runs immediately
)(jQuery);

...which shadows the $ symbol locally within the anonymous function (which is defined and called at the same time). jQuery makes this particularly easy if you're using its ready event:

jQuery(function($) {
    // Your usual jQuery code here using `$`,
    // this code runs when the DOM is ready (see
    // the `jQuery.ready` function).
});
like image 42
T.J. Crowder Avatar answered Jan 27 '23 19:01

T.J. Crowder