toggle issue for timeline [duplicate] - javascript

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);

Related

get instance of load() function in nashorn

How can I go about getting an instance of a script that is loaded in Java Script?
I'm using the function load("script.js") and I need to call a function on that script, but I need the instance in a variable so i can store it in a map.
I need something like var script = load("script.js")
Then I can call script.unload() // a function defined in script.js
When you load a script, it's executed and any bindings it creates in the environment are created. You cannot unload a script. If you know what all of its bindings and other effects are, you could clear them all (for instance, if loading Underscore, you could do _ = undefined to clear that binding), but it's unlikely that all of the effects of loading the script will be undone.
(This isn't a Nashorn thing, it's a JavaScript thing. There's one environment shared by all loaded scripts. ES2015's modules help organize that better, but there's still just one overall environment.)

Multiple calls to jQuery.noConflict() on the same page

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);

Where to put javascript events in AMD modules?

I am in the process of converting a massive .js file into AMD modules using requirejs
I realise the concept about returning function and such which are much link classes, however, how do I handle events such as:
$('blah blah').onClick( ...
$('blah blah 2').onChange( ...
Do I just create a module that does not return anything? What is the best way to handle these sorts of things?
If you want to be executed just once, at application initialization, just put it in the body of your module and don't return anything:
define([...], function() {
// All code here will be executed once at initialization.
});
All the body code will be executed once, as long as you import that module. This is a bad idea for jQuery selectors as there is no guarantee that the DOM will be properly loaded when this is evaluated.
If you need to call your code manually, once or more, encapsulate it in an object and you can import and call it when needed:
define([...], function() {
return {
registerEvents : function () {
// All code here will be executed when `module.registerEvents()` is called.
}
};
});
This would be the proper way to register DOM events as it gives you more control in regards of when this is evaluated.
Since selecting an element an attaching a handler with a jQuery selector happens over the whole document, it can technically be put anywhere.
I would say it largely depends on how you're organizing your modules.
If you're splitting them up into MV* components, interaction handlers would go in the V* portions (e.g. a Backbone View).
If you're using some other organizational scheme, generally I'd say put the handlers where they're the most tightly bound. For example, if a module already has a reference to the DOM element you want to bind to, put the handler in with it (and use that specific reference, rather than calling $() to traverse the document, potentially picking up unwanted elements) so that you can unbind the handler at the end of the lifecycle of the element.

Why wrap every prototype "class" object with an anonymous function in JS?

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.

Is there any benefit to defining a utility function directly on the jQuery object?

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:)

Categories

Resources