start javascript code with $(function, etc - javascript

I am studying Backbone and the todo example apps from http://todomvc.com/
I have noticed there are 3 severals ways of starting the code in the files:
$(function() {
// code here
});
$(function( $ ) {
// code here
});
(function() {
// code here
}());
I do not understand the differences and when I should use one over the other.
I also saw some people using this to start their code:
$(document).ready(function(){
// code here
});
From what I have seen, this is the full way of writing it right?
In a more general way, should I always include my javascript code into something like that in each files?
Thanks for your advice.

$(document).ready(function(){}) ensures that your code runs on DOM ready, so that you have access to the DOM. You can read more about this in jQuery's documentation.
$(function(){}) is just an alias to #1. Any code in here will wait for DOM ready (see the docs).
$(function($){}) is equivalent to #1 and #2, only you get a clean reference to jQuery in the local scope (see the note below). You can likewise pass in $ to the function in #1, and it'll do the same thing (create a local reference to jQuery).
(function(){}()) is just a self-executing-anonymous-function, used to create a new closure.
Please note that none of these are specific to Backbone. The first 3 are specific to jQuery, while #4 is just vanilla JavaScript.
Note: To understand what's going on in #3 above, remember that $ is an alias to jQuery. However, jQuery is not the only library that uses the $ variable. Since the $ might be overwritten by someone else, you want to ensure that within your scope, $ will always reference jQuery - hence the $ argument.
In the end, it basically boils down to the following 2 options:
If your JavaScript is loaded in the head, you have to wait for document ready, so use this:
jQuery(function($) {
// Your code goes here.
// Use the $ in peace...
});
If you load your JavaScript at the bottom of your document (before the closing body tag - which you should definitely be doing), then there's no need to wait for document ready (since the DOM is already constructed by the time the parser gets to your script), and a SEAF (A.K.A. IIFE) will suffice:
(function($) {
// Use the $ in peace...
}(jQuery));
P.S. For a good understanding of Closures and Scope, see JS101: A Brief Lesson on Scope.

I guess it makes sense to start out, by realizing that $ = jQuery. The purpose of which down below when reading about namespaces within anonymous functions will make more sense. But in essence, you can use either of them. One would use jQuery() instead of $() if they were using multiple libraries, and wanted the $ to be used by the other one.
$(document).ready(function(){
// Here we have jQuery(document) firing off the ready event
// which executes once the DOM has been created in
// order to ensure that elements you are trying to manipulate exist.
});
​$(function () {
// Short-hand version of $(document).ready(function () { });
});
More information on Document.ready()
Putting the $ within the parenthesis ensures the jQuery $ alias (you can be safe it always signifies jQuery this way).
$(function ($) { /* code here : $ always means jQuery now */ });
Lastly you have an IIFE (Immidiately-Invoked Function Expression)
- IIFE explanation
(function (myNameSpace, $) {
// This is an anonymous function - it is ran instantly
// Usually used for namespaces / etc
// This creates a scope/wrapper/closure around everything inside of it
}(window.myNameSpace, jQuery));
The $ at the top (with it's matching jQuery on the bottom) signify that the
$ (dollar sign) stands for jQuery within the scope of the namepsace.
This is done to ensure that other libraries do not collide with what the developer
intends/wants the $ to be used with.
(function (myNameSpace, $) {
// Now because of all of this scope/wrapper/closure awesome...
// you can create -INTERNAL- variables (sort of like Private variables from other langs)
// this variable cannot be accessed outside the namespace unless it is returned / exposed
var internalVariable = '123'; // Internal
// Even Internal functions!
function privateFunction () {
console.log('this is private!');
}
// --------------------------------------------------------
// Public -method- of nameSpace exposing a private variable
// Notice we're using the myNameSpace object we exposed at the top/bottom
myNameSpace.nameSpaceMethod = function () {
privateFunction(); // we can call the private function only inside of the namespace
return internalVariable; // now we could get this variable
};
}(window.myNameSpace, jQuery)); // notice these mirror the above arguments in the anon function
More information on anonymous functions
Now if we're outside of the namespace, we can see how these internal/public methods and variables are effected:
// This will come up undefined
alert(internalVariable);
// This will trigger a -method- of the myNameSpace namespace - and alert "123"
// Showcasing how we access a Public method - which itself has access to the internal variable
// and exposes it to us!
alert(myNameSpace.nameSpaceMethod());
​

These two:
$(function() {
// code here
});
$(document).ready(function(){
// code here
});
Are directly equivalent, they are both the way to start some jQuery when the document has loaded. The former is just a shorter version of the latter.
This one:
(function() {
// code here
}());
is just a scoped function with zero parameters, which is immediately called with zero parameters.

Related

Calling function/nested function from external js file

I'm having some issues with running some functions from an external js file.
The html includes:
<script src="js/file.js"></script>
<script>
$("#center-button").click(function() {
explodePage("center");
});
</script>
The js file includes:
var explodePage = function(button) {
//code here
aboutPage();
}
var aboutPage = function() {
//code here
}
The explodePage function runs fine, but as soon as it reaches the call to the nested aboutPage function, it starts throwing these uncaught typeerrors at me. It works fine if I don't use an external js file and just put everything into the html. Pretty new to this so probably missing something obvious in scope or something. Any solutions?
Declare the function's definition as below:
function explodePage(button) {
//code here
aboutPage();
}
function aboutPage() {
//code here
}
Explanation:
When you use the var keyword for declaring functions, the execution of JS happens as when the variable is initialized, you cannot reference or use variable's before declaration. In contrast with the name function defintion JS interpreter first picks the enclosed functions before execution and initializes it before the code execution. This is called AST- Abstract syntax tree that is followed by JS interpreters.
Also Remember:
Also bind your Jquery code inside a Jquery document ready function, just to make sure the Jquery and the DOM elements are available for the bindings.
It's not a good a idea to pollute the global window object with variables, since there can be collisions. And immediately-invoked function expression is a good solution for this.
(function(){
//You can declare your functions in here, and invoke them below
$( document ).ready(function() {
//Check that the DOM is ready, in order to manipulate it an add events
$("#center-button").click(function() {
explodePage("center");
});
});
})($); //Notice that we are injecting a dependency, in this case jQuery

Seeking explanation of structure (Revealing Module Pattern)

RE: The Odin Project: Missile Command canvas game exercise.
This project has very few submissions (it's either very new or very difficult), and the two submissions available for reference are from people possessing more experience than I. In the more accessible submission is the following:
var missileCommand = (function() {
//---------
//hundreds of lines of game logic
//including 'initialize' and 'setupListeners' methods
//---------
return {
initialize: initialize,
setupListeners: setupListeners
};
})();
$( document ).ready( function() {
missileCommand.initialize();
missileCommand.setupListeners();
});
What is the purpose/meaning/structure behind the return and the subsequent method calls within the $(function)? I'm not sure what's going on, save that removing either set breaks everything.
I know the title isn't very descriptive, but I don't have enough information to do much about it. Will edit when I know what to call it.
There's two completely separate patterns here.
var missileCommand = (function() {
//---------
//hundreds of lines of game logic
//including 'initialize' and 'setupListeners' methods
//---------
return {
initialize: initialize,
setupListeners: setupListeners
};
})();
This is an implementation of the revealing module pattern. It allows you to create a module (missileCommand) which exposes a number of public methods (here, initialize, and setupListeners). It also allows you to define and store private methods and variables; which will be defined within the area you've commented.
$( document ).ready( function() {
missileCommand.initialize();
missileCommand.setupListeners();
});
This is a jQuery ready block. When the DOMContentLoaded event has fired, jQuery will run the function provided. Here, that function calls missileCommand.initialize(), then missileCommand.setupListeners().
More often, you'll see the ready block used to attach event handlers to elements;
$(document).ready(function () {
$('#some-selector').on('click', function () {
alert('Hello');
});
});
Note that both of my explanations are a rather short introduction to each subject. Both links (and further Google-ing of the terms), will give you much more detailed explanations.
$ is a jQuery object. What it does here is it binds an anonymous function (containing the two function calls, initialize() and setupListeners()) to the event "ready", which is fired when the document (DOM) is fully loaded.
you can translate that in jQueryFind(myElement).whenCompletelyLoaded(myFunctionToExecuteOnEvent()) (this is not functional code)
The return statement within the missileCommand function makes sure than when you do var myCommands = missileCommand() it returns an object containing both the values of the initialize function and the setupListeners function.
In those 100's of lines of code you would for sure find 2 function declarations matching: function initialize(){} and function setupListeners().
The object returned simply exposes those 2 functions by returning them to allow calling them as:
missileCommand.initialize();
missileCommand.setupListeners();
The properties of the returned object could have different names but author wanted the properties to match the function names....the values of the properties are simply references to the function object declared previously

Javascript Library Quickstart

I'm trying to build a Javascript library that will provide some functionality for a JQuery Plugin I'm putting together.
I got the following skeleton code from searching online although I'm not quite sure how it all works (I do know it's a closure). I've added my functions via declarations.
(function(window, document, $) {
function func_1(){
return 1;
}
function func_2(){
return 2;
}
})(window, document, jQuery);
So I put the above code in a separate JS file and then source it in my HTML page, then I run try to run the function like so (Note: I have JQuery set up as well):
<script type="text/javascript">
$(document).ready(function() {
console.log(func_1());
});
</script>
However, I seem to be getting some errors in Firebug (ReferenceError: func_1 is not defined).
I have two questions:
How do I call my functions?!
I'd like to be able to call the functions in the following format: className.functionName(). How do I restructure the skeleton code to enable me do this and, say, call my function like this: Device.func_1()?
Thanks for your anticipated assistance.
The closure is used to hide internal functions from the rest of the code. You need to explicitly expose the public functions of the library:
var Device = (function(window, document, $) {
function func_1(){
return 1;
}
function func_2(){
return 2;
}
var internalDevice = {
func_1: func_1,
func_2: func_2
};
return internalDevice; // expose functionality to the rest of the code
})(window, document, jQuery);
The (function(window, document, $) {})(window, document, jQuery); part is called an immediately invoked function expression (IIFE). It's used to avoid leaking all the library functions into the global scope. Otherwise, if some other library had a func_1 function it would either be overwritten or overwrite your library's func_1.
The arguments to the function are used to control how the library can affect other parts of the code and relies on it. For example, someone might overwrite the window.$ library so that $ is no longer available everywhere in the code. But since you have a local reference in the closure you can still access it.
Alternatively to using the code above - returning an object - you could also assign your library directly to the global scope:
(function(window, document, $) {
...
window.Device = internalDevice; // expose functionality to the rest of the code
})(window, document, jQuery);
I can only answer question number two, but you can create that by doing this:
var Device = {
function func_1()
{
// your first function
},
function func_2()
{
// your second function
}
};
That way you can just call:
Device.func_1();
Hop that helps :)
When something is inside a closure the scope of it is changed to that closure. func_1 and func_2 can only be seen inside the anonymous function calling them and below.

Calling jQuery document.ready handler with apply method?

Below is the code I am using in a project with some complex dependencies. After I have made sure that all the dependencies have been loaded I fire the onReadyCallback() also given below. I have two questions :
Is it correct to use, anonymousHandler.apply(MyNameSpace), the apply method on an anonymous Handler being called for Document.ready
From what I understand, because I am using the apply method the anonymous function will fire immediately irregardless of document's ready state. Then how can I pass in the context of MyNameSpace to the anonymousHandler so that "this" inside the function refers to MyNameSpace
var onReadyCallback = function(){
jQuery(document).ready(function(){
if(!this.loggedIn()){
return;
}
...Lots of Code referring to MyNameSpace using "this"
}.apply(MyNameSpace));
};
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
onReadyCallback.apply(window);
});
});
How about this, using an anonymous function and call?
jQuery(document).ready(function() {
(function() {
// this == MyNamespace
}).call(MyNamespace);
});
Normally, the ready event jQuery function is called like this
$(function() { /* ... */ });
// or
jQuery(function() { /* ... */ });
// or
jQuery(document).ready(function() { /* ... */ });
Bottom line, the function is not given a particular context; the actual context given by jQuery to the function is the HTMLDocument element, regardless of the argument (in the last example, document). Why is this so is another subject.
Generally, each of these functions are called later, after everything has been loaded, but not necessarily. In your case, there is a reference to MyNameSpace before the ready event happens. Even if Javascript is a LALR-type language, and it will find the symbol declared later, this is not a good practice. What if MyNameSpace would be set to something else later on, before jQuery triggers the ready callback functions? Your ready callback would not get that new reference. Unless intentional, the reference should be made inside the ready callback, when everything is.... ready.
Then, inside the ready callback, there are other techniques to assign a context to a function. lonesomeday have pretty much given the correct way to accomplish what you are trying to do.
(function() {
// this == MyNamespace
}).call(MyNamespace);
The above code executes an anonymous function right away, where this == MyNameSpace
note : the difference between apply and call is decribed here
Now, comes the bottom part of the code you provided :
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
onReadyCallback.apply(window);
});
});
This is problematic, and unnecessary. Is the function onReadyCallback only needed there, or will it be called several times? If it needs to be called only once, spare the global namespace, and simply do :
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
// if everything is done loading, the function will be executed, otherwise
// it's execution will be postponed later
jQuery(function() {
// create our nicely wrapped anonymous function now
(function() {
if(!this.loggedIn()){
return;
}
// ...Lots of Code referring to MyNameSpace using "this"
})(MyNameSpace); // grab our most recent reference of `MyNameSpace`
});
});
});
If you don't like the indentation (it's merely a developer's taste), replace everything in the ready callback with (something like) :
initMyNameSpace.apply(MyNameSpace);
and create your function outside, on the global space :
function initMyNameSpace() {
if(!this.loggedIn()){
return;
}
// ...Lots of Code referring to MyNameSpace using "this"
};
But I would recommand, at least, to put it in the require callback function so it...
...does not pollute the global namespace with a run-once function
...is not accessible from anywhere (keep it private)
...can be found quickly when editing the source code
etc.
note : usually, apply and call are used to avoid repeatedly accessing objects like some.thing.pretty.deep = value; or when one function needs to be applied to many but not all objects, and thus extending the object's prototype is just not a good idea.
This is my opinion anyway, and how I would do things, without any more knowledge of your code or what you are doing.

what does this construct do in javascript

i really tried to understand, what meaning the the following contruct has in JS, but i could not figure out:
how it works
why & in which situation this construct should be used?
Pls could someone can tell me? Thank you!
(function () {
...
}());
// Or in jQuery plugins i saw it very often
(function( $ ){
...
})( jQuery );
(function () {
...
}());
Defines a function. Calls it immediately. Doesn't store it anywhere.
Usually used to limit the scope of variables inside it.
(function( $ ){
...
})( jQuery );
Exactly the same, except it has an argument. Used so the unhelpfully non-descriptive variable $ can be used without having namespace conflicts with all the other libraries that thought $ was a good name for a variable.
This is called Closure and it's main point is to encapsulate your inner code in order not to mix it with a global scope.
Read this for more details
The second part
(function( $ ){
...
})( jQuery );
Is used to enable your code to use $ as a reference to the jQuery object, without it conflicting with other javascript libraries (like Prototype).
See the jQuery documentation:
http://docs.jquery.com/Using_jQuery_with_Other_Libraries#Referencing_Magic_-_Shortcuts_for_jQuery
These are closures. There is tons of information on this style of JavaScript programming but the gist of it is that its an immediately executing function. If you look closely at the syntax this makes perfect sense -
( ) causes an execution to take place.
//Function immediately executes.
(function() {
});
//Wait we can do better, let's pass in an argument
(function($) {
//$ is now a local variable inside this tightly scoped function
//So that I can describe this as a closure I've added members to this function
var foo = 0,
bar = function() {
return foo;
};
return {
foo: bar
};
}(jQuery));

Categories

Resources