We've developed a page with whole bunch of functionality implemented as separate components.
The jQuery itself is included into the page header only once.
But each component has exact the same piece of javascript code:
j$ = jQuery.noConflict();
Could these multiple calls to jquery's noconflict on the same page and assigning the result to the same variable create some problems (e.g. with using plugins) ? Is it acceptable ? I would expect it to work as a singleton, i.e. always returning reference to the same internal object and no matter what.
Thanks in advance for your help, folks!
jQuery.noConflict()
Many JavaScript libraries use $ as a function or variable name, just
as jQuery does. In jQuery's case, $ is just an alias for jQuery, so
all functionality is available without using $. If you need to use
another JavaScript library alongside jQuery, return control of $ back
to the other library with a call to $.noConflict(). Old references of
$ are saved during jQuery initialization; noConflict() simply restores
them.
In your case, multiple calls should be no harm, as it is an idempotent function.
In case you plan to include such components in an unknown environment, it is a safe practice to call it before proceeding.
Consider using a self-executing anonymous function in order to bind it to your context:
(function($){
// here $ will be the global, common jQuery object you passed as an argument
})(jQuery);
Related
I'm looking through the excellent peepcode demo code from the backbone.js screencasts. In it, the backbone code is all enclosed in an anonymous function that is passed the jQuery object:
(function($) {
// Backbone code in here
})(jQuery);
In my own backbone code, I've just wrapped all my code in the jQuery DOM 'ready' event:
$(function(){
// Backbone code in here
});
What's the point/advantage of the first approach? Doing it this way creates an anonymous function that is then executed immediately with the jQuery object being passed as the function argument, effectively ensuring that $ is the jQuery object. Is this the only point - to guarantee that jQuery is bound to '$' or are there other reasons to do this?
The two blocks of code you have shown are dramatically different in when and why they execute. They are not exclusive of each other. They do not serve the same purpose.
JavaScript Modules
(function($) {
// Backbone code in here
})(jQuery);
This is a "JavaScript Module" pattern, implemented with an immediately invoking function.
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
The purpose of this code is to provide "modularity", privacy and encapsulation for your code.
The implementation of this is a function that is immediately invoked by the calling (jQuery) parenthesis. The purpose of passing jQuery in to the parenthesis is to provide local scoping to the global variable. This helps reduce the amount of overhead of looking up the $ variable, and allows better compression / optimization for minifiers in some cases.
Immediately invoking functions are executed, well, immediately. As soon as the function definition is complete, the function is executed.
jQuery's "DOMReady" function
This is an alias to jQuery's "DOMReady" function: http://api.jquery.com/ready/
$(function(){
// Backbone code in here
});
jQuery's "DOMReady" function executes when the DOM is ready to be manipulated by your JavaScript code.
Modules vs DOMReady In Backbone Code
It's bad form to define your Backbone code inside of jQuery's DOMReady function, and potentially damaging to your application performance. This function does not get called until the DOM has loaded and is ready to be manipulated. That means you're waiting until the browser has parsed the DOM at least once before you are defining your objects.
It's a better idea to define your Backbone objects outside of a DOMReady function. I, among many others, prefer to do this inside of a JavaScript Module pattern so that I can provide encapsulation and privacy for my code. I tend to use the "Revealing Module" pattern (see the first link above) to provide access to the bits that I need outside of my module.
By defining your objects outside of the DOMReady function, and providing some way to reference them, you are allowing the browser to get a head start on processing your JavaScript, potentially speeding up the user experience. It also makes the code more flexible as you can move things around without having to worry about creating more DOMREady functions when you do move things.
You're likely going to use a DOMReady function, still, even if you define your Backbone objects somewhere else. The reason is that many Backbone apps need to manipulate the DOM in some manner. To do this, you need to wait until the DOM is ready, therefore you need to use the DOMReady function to start your application after it has been defined.
You can find plenty of examples of this around the web, but here's a very basic implementation, using both a Module and the DOMReady function:
// Define "MyApp" as a revealing module
MyApp = (function(Backbone, $){
var View = Backbone.View.extend({
// do stuff here
});
return {
init: function(){
var view = new View();
$("#some-div").html(view.render().el);
}
};
})(Backbone, jQuery);
// Run "MyApp" in DOMReady
$(function(){
MyApp.init();
});
As a minor sidenote, sending in $ as an argument to an anonymous function makes $ local to that function which has a small positive performance implication if the $ function is called a lot. This is because javascript searches the local scope for variables first and then traverses down all the way to the window scope (where $ usually lives).
It ensures you can always use $ inside that closure even if $.noConflict() was used.
Without this closure you'd be supposed to use jQuery instead of $ the whole time.
It is to avoid a potential conflict of the $ variable.
If something else defines a variable named $, your plugin may use the wrong definition
Refer to http://docs.jquery.com/Plugins/Authoring#Getting_Started for more details
Use both.
The self invoking function in which you pass in jQuery to prevent library conflicts, and to just make sure jQuery is available as you would expect with $.
And the .ready() shortcut method as required to run javascript only after DOM has loaded:
(function($) {
$(function(){
//add code here that needs to wait for page to be loaded
});
//and rest of code here
})(jQuery);
Looking at this JS code by David Fowler he wraps every "class" with an anonymous self executing method where he sends in jQuery and window. I get that this is a way for ensuring that $ and window are actually the global jQuery and winndow variables you'd expect them to be.
But isn't this a bit over-protective? Should you protect yourself from someone else changing the $ and window variable - is there actually code that does that, and if so why? Also, are there other advantages to wrapping everything like this?
If I remember correctly there are some other libraries than jQuery using the $.
The concept of using function context to create local / function scopes is all about to protect your own code. This especially makes sense if you expect your Javascript code to run in an environment where multiple other (maybe even unknown) scripts may get loaded.
So, if some other Javascript code which got load before your own, assigns window.$ with some other value (it might load the prototype framework for instance), then your code is already screwed if you try to access jQuery specific things.
Another point there is the "a--hole"-effect. Someone creates a line like
window.undefined = true;
...
Now, all your checks against undefined will pretty much fail. But by explicitly creating those variables/parameters and filling them with the values you expect, you can avoid all those problems.
(function(win, doc, $, undef) {
}(window, window.document, jQuery));
Generally most top-level JavaScript code should be wrapped in an IIFE, whether they pass in particular variables or not. This prevents variables created with var from polluting the global scope.
Another small benefit is minification: if you minify your code, making window into a "local variable" by passing it in as a parameter allows the minifier to rename it. This benefit goes away if you gzip, however, so it's not a real win.
Mostly people just pick a pattern for their IIFEs and stick with it, so in his case he's decided this is they way he writes his .js files and he does so uniformly. Having a uniform standard is valuable in and of itself.
To clarify, the code can be written in slightly longer form with
(function () {
var $ = jQuery;
var window = window;
// ...
}());
The code inside the anonymous function is the the function scope, so it prevent confliction with the global variables.
Imaging that if every jQuery plugin is not wrapped in a anonymous function, then there will be a global variables hell.
It's just to preserver integrity.
$ can be Prototype, so sending jQuery as argument will save your code if someone else add a library/variable which overwrite $.
About the second argument "window", I see it as a module you want to write on.
Are there any specific benefits derived from defining a utility function directly on the jQuery object:
For instance, given the following two constructs:
$.someUtility = function(){
//do some something with jQuery
}
var someUtility = function(){
//do some something with jQuery
}
Is there any specific reason I would want to use the first example over the second?
Quick Update:
I don't need to do any chaining, and my utility is not a plugin in the traditional sense; It will not perform any operations on a jQuery selector.
You're simply borrowing the global jQuery function object to make your function available to other scripts without further polluting the global variable environment.
If you have no other scripts that rely on that function, you could make it a local variable with no disadvantage except that you'd be polluting your local variable environment.
If you're strictly writing a utility function as opposed to a wrapper method I think the main benefit would simply be that your coding style would be more consistent. A consistent style could be important to you if you plan on using the function on more than a single page.
Three good reasons can be found for choosing to append functions directly on the JQuery object:
you want to build a JQuery plugin (most obvious reason)
the function you are programming applies to DOM nodes, so it could be directly applied to the DOM nodes returned by a JQuery query (sorry for the rhyme)
to keep consistency throughout your code, as you will be lead to use the $ object
Use $.fn.someUtility.
Basically, the first option is creating a jQuery plugin. This allows for your code to be easily reusable in the jQuery context. Inside a jQuery plugin, the this identifier points to the element that was selected in the jQuery selector, allowing for more flexibility when manipulating elements.
I guess the answer to your question is that it really depends. Are you using your function in multiple places?
See JQuery Plugins for more information.
The reason is that your function can then operate on arrays of jQuery-wrapped objects without jumping through the usual hoops. Also in the context of your function, this becomes a reference to the jQuery object on which your function was invoked.
EDIT
My answer assumed defining your function under $.fn.func.
Unless you require access to jQuery selected elements, the only benefit I can see would be by defining under $.func is that you avoid name collisions with other functions defined in the global scope. (As mentioned in my comment below.)
If your utility function uses jQuery (and thus requires it's presence), then I'd say you can use their namespace and put it under $.fn.myUtility as others have recommended. If your utility function is entirely independent of jQuery and does not use it at all and you are likely to have other such utility functions to go with it, then I would tend to make my own global namespace and put your function there such as JLF.myUtility. This makes your code a little easier to reuse in the future even in non-jQuery project.
For me, jQuery gets a lot of it's flexibility and power from the "daisy chain" setup, since every plugin returns "this" you can always call another plugin immediately after, not to mention you are extending an already powerful tool, and that seems like a good idea:)
in my webapp I have a variable like this
var data = {
getItem: function(key){
...
}
}
In all of my scripts I can use
data.getItem("Test");
But how can I use it in jquery plugins? Plugins often have following structure
(function($, window, document) {
//....plugin-code
});
How do I call this kind of structure? Is it possible to use my global data variable in such plugins?
If your data variable is global, then yes you can use it anywhere, including inside jQuery plugins.
You'll need to make sure that data is defined before any self-executing functions that are going to use it.
Actually they tend to have structure
(function($) {
// plugin-code
})(jQuery);
the points being that
they can assume that $ in this scope will always be jQuery, regardless of anything else loaded that defines $ e.g. prototype
everything is defined inside this closure and so only what you choose to expose (by $.fn or $.extend) is leaked out to the outside world
Obviously if it's just your plugin in your environment where you can assume you're always running $ = jQuery then you don't need these. (Yours also has document and window: I've never seen these overridden and I'm not sure what you'd pass in as arguments here other than document and window themselves?)
Were you asking about defining data inside the plugin or pulling it in from outside the plugin scope? There's no restrictions of what you can write inside, so if you define and use it inside then your code will work exactly as befoer. If you need to access data defined inside from the outside then you'll need to leak it out somehow, e.g. adding an accessor method to one of $, document or window.
If you're pulling in data from outside the plugin scope then you can still access global variables from inside your closure, or you could pass it in as an extra argument - I don't think it'd make any difference.
I was recently listening to a podcast which made a comment on using $() vs using jQuery(). It was stated that every time $() was used a new object would be created and when jQuery() was used this was not the case. I google'd around but couldn't find anything on this specific topic.
I realize this is not a typical example, but the following is the reason I am interested in the answer to this question.
I have a page that the user will keep loaded in a browser for a whole day (24 hours, or possibly longer) and updates are done to the DOM every ~5 seconds as the result of an AJAX call via jQuery (the AJAX call portion is irrelevant to updating the DOM - the update to the DOM is done using a string of HTML and a call on a jQuery object to .empty() and then .html()).
Since hearing this, I subsequently switched all of the $() calls to jQuery() calls, but I would like to know:
Is using $() vs using jQuery() a bad practice? Is there a negligible difference between the two? Or is it actually noticeable on larger projects?
No, it's not bad practice, and there is no performance difference.
The $ and jQuery identifiers refer to the same function instance.
This is done by the last line of jQuery.js:
window.jQuery = window.$ = jQuery;
The only problem with using $() over jQuery() is the possibility that another Javascript framework uses it as well.
Nope - take a look at the jQuery source code. $ is just another alias for jQuery - the last line says it all:
window.jQuery = window.$ = jQuery;
See here for yourself:
http://code.jquery.com/jquery-latest.js
To me, the goal is to avoid naming collision with other libraries that also use $ as main object, like Prototype, if you want to use both libraries on the same page, or you don't know where your code will be used...
Are you sure it was $() vs jQuery()? Maybe the more salient point is that there are performance hits to doing either, and many new js coders use $() unnecessarily when plain js could do.
It's good practice to avoid creating a jQuery object when you don't have to.
As stated before, the only real problem is getting into conflict with other js frameworks used, therefore i find this is the most handy solution to be still able to use the dollar sign, but have no conflicts and make your code more portable:
(function($) { /* some code that uses $ */ })(jQuery)
http://docs.jquery.com/Using_jQuery_with_Other_Libraries#Referencing_Magic_-_Shortcuts_for_jQuery