breaking down jquery code [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does jQuery protect overwriting jQuery and $
I am looking over jQuery source code and there are several lines of code which I don't get.
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
My question is what is the code above doing? How does it work? I imagine that it is responsible for the jQuery and $ objects, but I can't wrap my head around it.

If you look at the sourcecode of the noConflict function you will see this
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
When Jquery load, it overwrite global $ and jQuery. noConflict return these global variables to its former value from backups. These backups were create with the code you mentioned.

Many libraries using javascript use $. It is resetting the $ so that other libraries like
Prototype can use $ without causing conflict errors. If that wasn't done, the code could not work and could cause errors.

That is used in the context of the jQuery function to:
1) Prevents client code from overriding the functionality of jQuery and $ functions.
2) Alias the jQuery and $ functions to increase speed.

Related

What's the difference between using (document).ready and jQuery(function ($)? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between these jQuery ready functions?
I have always used:
$(document).ready(function (){
//Code goes here
});
And inserted my jQuery/JavaScript code therein (so that it waits on the html page to be fully loaded before running any code).
Lately, I have seen this:
jQuery(function($){
//Code goes here
});
I have searched for what the difference is here (mainly what the 'jQuery' part is all about).
My questions:
What does the jQuery part of the latter code block do, if anything?
What is the '($)' argument doing for that function?
Is there even a difference (other than making the page wait to be loaded) between my two code block examples?
The main difference is the closure around the $ variable. The first snippet assumes that the $ variable has not been released (by using .noConflict() or if another library you are using also makes use of $ but not as the jQuery variable).
The second implementation is safer because it doesn't make any assumptions but allows your internal code to safely use the $ variable by making it a parameter.
It is the same thing:
Using jQuery(function(){}) is just a shorthand for $(document).ready(function (){});
Note: you can use $ or jQuery
They're the same. From the documentation:
JQuery Call back (jQuery( callback ))
"This function behaves just like $(document).ready(), in that it should be used to wrap other $() operations on your page that depend on the DOM being ready. While this function is, technically, chainable, there really isn't much use for chaining against it."
They are nearly the same.
In the second function you are passing in jQuery i.e. $ into the function. $ is shorthand for the jQuery.
Straight from the jQuery library code for when you call $()
// tests to see if you passed in a function
} else if (jQuery.isFunction(selector)) {
// adds the function to be called when jQuery fires the ready event
return rootjQuery.ready(selector);
}
Comments are mine.

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?
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.
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).
});
If you were to include another library like prototype, which uses $, then jQuery needs to have a reference of both $ and window.jQuery in order to support the jQuery.noConflict() function, etc...
http://api.jquery.com/jQuery.noConflict/
$ is used because it is convenient, but this comes at the price that it may be used by more than one library.
Does that help?
Javascript doesn't have the means of providing the kind of protection you are looking for.
JQuery isn't "protecting" those variables. It's just copying the references $ and jquery into two other variables. The code you have read is equivalent to:
var obj1 = {}; /* create an empty object and reference it as obj1 */
var obj2 = obj1; /* made a second reference to that same object */
This code doesn't "protect" obj1. It's perfectly valid that your code later on changes the value of obj1:
obj1 = 'foo'; /* now obj1 references a string */
obj1 doesn't "magically retain its value"; after that line, it's just a string. But the object is still available in obj2.
The purpose of those lines is to be able to restore the original $ and jQuery global variables in case jQuery itself overrides them. It doesn't do anything to protect other code from overriding jQuery.
If you want to protect your own namespace, you can do a setInterval that checks if the global variable is still an instanceof your object (only if your object is protected inside a closure, otherwise it can be modified too). But, this isn't good practice, as the idea of javascript is to be able to extend and customize. Put the control in the hands of the developer, don't try and "lock in" your objects.

$ vs. jQuery: Which should I use?

What is the diffrence between them? Which is better?
$ is an alias for jQuery, neither is "better" really, jQuery is provided in case something else is using $, like Prototype (or jQuery.noConflict() was called for another reason...).
I prefer $ for brevity because I know it refers to jQuery, if you're unsure (like when writing a plugin) use jQuery for your primary reference, for example:
(function($) {
//inside here $ means jQuery
})(jQuery);
The functionality is identical if there is no conflict.
Use 'jQuery' instead of '$' to be especially explicit/descriptive, or if you currently use or anticipate using another library that defines '$'.
See also http://api.jquery.com/jQuery.noConflict/
jQuery == $ == window.jQuery == window.$
jQuery and $ are defined in window, and $ can be used if no other library is making use of it, thus creating conflicts.
Either use jQuery.noConflict() or closures:
(function ($) {
// code with $ here
})(jQuery)

How to make custom, no editing need, bulletproof jquery's noconflict version?

in my job i always have to use jquery with prototype can i make any custom jquery with library file like once i will add in head and then no need to change anything in any code.
is it possible?
I don't want to change anything in an code $ to jQuery.
from http://www.cssnewbie.com/runing-jquery-with-other-frameworks-via-noconflict/
Keeping it Short
The noConflict mode does have one other bit of functionality that I’ve found useful in some of my projects: you can select a different variable to use instead of the standard “jQuery”. The usage looks like this:
var $j = jQuery.noConflict();
Now in addition to using the default jQuery() notation, I can also use the shorter $j() notation. This allows me to avoid running into problems with other frameworks, while still enjoying almost the same conciseness in my code.
This just begs the question why dont you simply implement all your stuff in Prototype then - or implement everything in jQuery. Overall they both have the same capabilities.
However to directly answer your question - ther isnt really a way to make a custom build of jQuery. But you could simply put your noConflict call immediately following your inclusion of the jQuery library.
Then for your stuff you can simply wrap it all in
(function($){
// your jQuery code here... Can be used with $ as normal.
})(jQuery);
within that function youll be able to use $ as the alias - outside of it you would need to use jQuery. The only gotcha here is that if you want a variable defined inside here to be global youll need to make it that way manually as everything within this will be scoped to the function. You can do this like so:
(function($){
window.myGlobalVar = 'This is a global variable';
})(jQuery);
The best thing is often to wrap the $ in a private scope:
(function($) {
// jQuery stuff
})(jQuery)
You can also call the jQuery.noConflict() function before the wrap: http://api.jquery.com/jQuery.noConflict/
Another clean option is chaining the noConflict() into a domReady callback:
jQuery.noConflict()(function($){
// code using jQuery or $
});
console.log(typeof $ === 'undefined') // prints true
To address your question of whether you can have an "include-once" file, yes, you could do something similar to:
/* MyLibLoader.js */
document.write("<script type='text/javascript' src='prototype.js'></script>");
document.write("<script type='text/javascript' src='jquery.js'></script>");
window.$j = jQuery.noConflict();
And then in HTML
<head>
<script type='text/javascript' src='MyLibLoader.js'></script>
</head>
But this approach assumes you're happy to change your jQuery usage to $j

Unify $ function of Prototype and JQuery

Is there any JavaScript function that can unify $ function from both Prototype and jQuery?
Yes, this is the real use case I am facing now. I find $ function in Prototype and $ in jQuery is conflicting each other. I know that we could us jQuery.noConflict() to ressign $ back to Prototype, however by doing so, I will have to rewrite jquery-specific javacript code that use that $ function, or have jquery specific in a code block (eg. anonymous function).
Is there any easier way, without having to rewrite existing code in both library and have them in one page?
The code that could answer this question may look like this, and your feedback is greatly appreciated:
<script type="text/javascript" src="/path/to/prototype.js"></script>
<script type="text/javascript" src="/path/to/jquery.js"></script>
<script type="text/javascript">
/* <![CDATA[ */
var $j = jQuery.noConflict();
var $p = $; // reference to prototype's $
var $ = function(E, F){
var isJQuery = true;
//TODO: logic to determine which $ to use here YOUR SUGGESTION HERE ;-)
var result = null;
if(isJQuery){
result = $j(E, F);
} else { // prototype
//TODO: code to delegate prototype $
}
return result;
}
/* ]]>*/
</script>
// ... any existing javacode jQuery and Prototype using $ function.
Thanks.
update: Rewrite question to be more clear.
Well, first of all, I can rarely find usefull cases where both of the libraries have to be included in the same page. So you might consider to remove one.
I guess that this is due to a plug-in use, but have a look at the opponent plug-in list, I'm quite sure that there is an alternative.
Second, for your jQuery specific code, it's quite easy to rewrite it, using the anonymous function trick:
(function($){
... your code here ...
})(jQuery);
This will work in most of the cases where you don't put global variables or methods rather than binding them to events.
I've always got into the habit of putting all my jQuery code into a function, similar to gizmo's example:
jQuery(function($) {
// jQuery code here, using $
});
this is the same as the document.ready event handler.
jQuery's been great about making sure they play well with Prototype. Check this page for details, Avoiding Conflicts with Other Libraries.
I've seen both libraries used in the same pages before and it is generally because of third-party apps that are in your pages that use one library while your pages use the other. However, if you're doing all the development yourself, I suggest sticking with one or the other.

Categories