So I started learning javacript and I've noticed that the coding convention for functions and callbacks is something like this (this is a jQuery example but I've seen these everywhere):
$.getJSON('some/url.json', function(a) {
// do stuff with a here
});
Coming from other languages, I would usually write the above as this:
function myFunction(myVar){
//do stuff with myVar here
};
$.getJSON('some/url.json', myFunction());
Why is the former usually the preferred way of writing in JS, instead of the [probably more readable] latter?
There are plenty of good reasons to use the second, more explicit, format (assuming you fix the issue listed in the comment), including:
reusing the function passed as a callback
giving that function a definitive name to make it easier to debug
making sure that function is noted as something important in your system
separating out that functions because it's simply too long to comfortably declare in place
But the first format, with an anonymous function passed as a callback is short and sweet. If you don't need to reuse the function, if it's relatively short, and if it's not of high importance in your system, it can be really useful to declare it exactly where you use it. You avoid adding another variable to your scope, and you make it entirely clear exactly what that function is for.
It's not the preferred way. You can do anything you want. However, if you need to reuse the function, then you need to do your second option, or alternatively the following, for code reuse:
// in some accessible context/namespace
App.myCallback = function(a){
...
};
// somewhere else
$.getJSON('url', App.myCallback);
Your first example is what is referred to as an anonymous function or block. They are used when they'll only be called once. The second example is when you'd use the function many times... it would be a lot of wasteful typing if you repeated the anonymous block over and over.
Related
So I had an interview where I was asking the purpose of declaring and calling a function immideately, and i couldn't answer it, i.e:
(function(){
// code
})();
What's the reason for doing this?
Object-Oriented JavaScript - Second Edition: One good application of immediate (self-invoking) anonymous functions
is when you want to have some work done without creating extra global
variables. A drawback, of course, is that you cannot execute the same
function twice. This makes immediate functions best suited for one-off
or initialization tasks.
The syntax may look a little scary at first, but all you do is simply
place a function expression inside parentheses followed by another set
of parentheses. The second set says "execute now" and is also the
place to put any arguments that your anonymous function might accept:
(function() {
})();
or
(function() {
}());
are the same:
Is there difference between :
(function() {
/*..........*/
})();
and :
(function($) {
/*..........*/
})(jQuery);
Other people explained what the difference is, but not why you use the latter.
The $ variable is most often used by jQuery. If you have one script tag that loads jQuery and another that loads your code, it's perfectly fine. Now throw prototype.js into the mix. If you load prototype.js and then jQuery, $ will still be jQuery. Do it the other way around and now $ is prototype.js.
If you tried to use $ on such a page, you'd likely get errors or weird behavior.
There are many questions on StackOverflow about this problem. Plugins shouldn't assume much about the page they're loaded in, so they use this pattern defensively.
i am asking if there is difference between (function(){/…/})(); and (function($){/…/})(jQuery);
A little difference. In case of (function($){/*…*/})(jQuery); and absense of jQuery you'll get an error message immeditally after page loads. It's a simpler to detect jquery absense or incorrect order of scripts inclusion, when jquery-based code included before jQuery.
In case of (function(){/*…*/})(); you'll get an error message when code inside this construction actually call one of jQuery methods. It's harder to detect this error, but on the other side you can include your jquery-based scripts before jquery.
I prefer first case.
The second form, (function($){/*…*/})(jQuery); can be slightly safer when working in an environment where you don't (or can't) strictly enforce what code gets put on your site.
I used to work on a large site with a lot of third-party ads. These ads would often unsafely inject their own version of jQuery and occasionally they would override jQuery's global $ object. So, depending on how we wrote our code, we might be calling methods that no longer existed or had slightly different behaviour from what we expected. This could be impossible to debug, since some ads would never appear in our area or were excluded from our environment. This meant we had to be extremely protective of scope, inject our dependencies before any ad code had a chance to load, namespace anything that had to be global and pray no ad screwed with us.
Other answers are quite fragmented so I'd like to give a more detailed answer for the question.
The main question can be self-answered if you understand..
What does (function(argument){ /*...*/ })(value); mean?
It's a quick hand version of:
var tempFunction = function(argument){
/* ... */
}
tempFunction(value);
Without having to go through the hassle of conjuring up a new terrible name for a function that you will only call once and forget. Such functions are called anonymous functions since they aren't given a name.
So (function(){/*...*/})() is creating a function that accept no argument and execute it immediately, while (function($){/*...*/})(jQuery) is creating a function that accept one argument named $, and give it the value of jQuery.
Now that we know what the expression means, surely the first think on our mind is
"Why?". Isn't $ jQuery already?
Well, not exactly. We can never be sure. $ is an alias of jQuery, but other libraries can also use the same alias. As user #FakeRainBrigand already pointed out in his answer, prototype.js also use $ as its alias. In such cases, whichever library assigns its value to $ later wins out.
The practice of (function($){...})(jQuery) is very similar to an alias import in other programing languages. You are explicitly telling the system that your function:
Requires an object/library named jQuery, and
Within your function, $ means jQuery.
So even when someone include a new library later that override the alias $ at the global level, your plugin/framework still works as intended.
Because javascript is so... "flexible" in variable assignment, some people (including me) go as far as doing things like
var myApplication = (function($, undefined){ ... })(jQuery);
Apply the same understanding, it is easy to interpret the second argument part as: assign nothing to the variable undefined. So we can be sure that even if some idiot assigned a value to undefined later, our if(checkVariable === undefined){} won't break. (it's not a myth, people really do assign values to undefined)
When is it commonly used in javascript?
This anonymous function practice is most commonly found in the process of providing encapsulation for your plugin/library.
For example:
var jQuery = (function(){
var publicFunction = function(){ /* ... */}
var privateFunction = function(){ /* ... */}
return {
publicFunction : publicFunction
}
})();
With this, only jQuery.publicFunction() is exposed at the global scope, and privateFunction() remains private.
But of course, it is also used any time you simply want to create a function, call it immediately, and throw it away. (For example as a callback for an asynchronous function)
For the bonus question
why they used (function(){}() twice in the below code?
Well, most likely because they don't know what they're doing. I can't think of any reason to put nested function in like that. None at all.
(function(){/*...*/})(); does not set $ as reference to jQuery within IIFE and (function($){/*...*/})(jQuery); sets $ or other parameter name; e.g.; (function(Z){/*...* Z("body") where Z : jQuery*/})(jQuery); as reference to jQuery within IIFE
The they are both closures. The first is just an anonymous function that will fire any well formatted code that is inside immediately. The second is the jQuery closure. It is how the jQuery library initiates it wraps its code in the JQuery object and exposes it isn't the $ symbol.
(function(){}()) // this is a closure
(function($){}(jQuery)) // is a closure that wraps the executed code inside of the jQuery returned object and exposes it via the $.
With this (function(){/*…*/})();, you are not passing any argument to the inner function, while with this (function($){/*…*/})(jQuery); you are passing jQuery as argument to the inner function and expecting its value as $(which means, you will be able to use jQuery inside the inner function).
Ex:
(function($){
$(document).ready(function() {
console.log('all resources loaded');
})
})(jQuery);
They both are examples of Immediately Invoked Function Expression. In that sense, there is no difference between (function(){/*…*/})(); and (function($){/*…*/})(jQuery);. So no benefits are gained by wrapping (function($){/*…*/})(jQuery); inside (function(){/*…*/})();
A new execution context is created when a function is executed. So when (function(){/*…*/})(); is executed a context is created. Again when (function($){/*…*/})(jQuery); is executed, another context is created. Since the first context is not used (i.e. no variables are declared inside it), I don't see any advantages gained by the wrapping.
(function() { // <-- execution context which is not used
(function($) { // <-- another execution context
"use strict";
/*..........*/
})(jQuery);
})();
I recently joined a large software developing project which uses mainly JavaScript and a particular question has been on my mind since day one. I know this issue has been here on SO before, but I have never seen the core question being properly answered. So here I ask it again:
Are there any benefits in JavaScript in using function expressions rather than function declarations?
In other words, is this:
var myFunction = function () {
// Nice code.
}
in any way better than this:
function myFunction () {
// Nice code.
}
As I see it, function expressions only introduce negative aspects on several levels to the code base. Here I list a few.
Function expression as the one above, suddenly forces you to be careful with forward references, as the anonymous function object that the myFunction variable refers to, does not exist until the variable expression actually executes. This is never a problem if you use function declarations.
Apart from generating twice as many objects as in the case with function declarations, this usage introduces a very bad programming habit, which is that developers tend to declare their functions only when they feel they need them. The result is code that mixes object declarations, function expressions and logic in something that obscures the core logic of a piece of code.
As a side effect of 2), code becomes much harder to read. If you would use proper function declarations and only var declarations for objects that actually will be variable in the code, it becomes far easier to scan the indentation line of code segment and quickly find the objects and the functions. When everything is declared as "var", you are suddenly forced to read much more carefully to find this piece of information.
As yet another nasty side effect of 2), as users get into the bad habit of only declaring their functions when they feel they need them, function expressions start showing up inside event handlers and loops, effectively creating a new copy of the function object either each time an event handler is called or for each turn in the loop. Needless to say, this is bad! Here is an example to show what I mean:
var myList = ['A', 'B', 'C'];
myList.forEach(function (element) {
// This is the problem I see.
var myInnerFunction = function () {
// Code that does something with element.
};
};
So to sum up, at least in my view, the only situation in which it is fair to use something like:
var myFunction = function () {
// Nice code.
}
is when your logic intends to change the myFunction reference to point at different functions during execution. In that situation myFunction (the variable) is something that is variable in the code, hence you are properly informing a different programmer of your intents, rather than confusing him/her.
With this background in mind, I ask my question again. Have I missed something central about function expressions (in the context described above) in which they provide any benefit over function declarations?
Do anyone can explain and prove which one of examples is "more correct"?
A: pass object as an argument
(function($){
$.doStuff();
})(jQuery);
B: retrieve object within the function
(function(){
var $ = jQuery;
$.doStuff();
})();
I really like B because of its readability. Only technical difference between A and B is that B has to lookup one more scope. I consider this as marginal difference so why is "recomended" the A way?
Note that the jQuery is just example. Important is the nature of the problem: Pass as argument or retrieve within the function?
The second way will only work if the name of the jQuery library is really "jQuery". It's possible (though unusual) to call .noConflict() like this:
window.banana = jQuery.noConflict( true );
Then, your first example would still work:
(function($) {
$.doStuff();
})( banana );
but your second example would fail (as written). Of course, you could similarly hard-code the name "banana" into the second one too, but if that function isn't directly under your control, you can't; plus it's a "DRY" violation.
Imagine that you've got an initialization function being loaded in a separate JavaScript source file; perhaps it's a 3rd-party script. If you want to call that function at initialization time, you'll have more flexibility if the function takes the jQuery reference as a parameter instead of just making the assumption that the global symbol is anything in particular.
alienInitializationFunction( banana );
will still work, in other words.
Both are equivalent, but I like the first example (passing as an argument) more as it saves you one line of code. That also means that your function does not contain unnecessary logic.
In my feeble attempt to learn JavaScript, I bought a book which teaches you how to do things in JavaScript, but forgets to mention WHY.
Coming from PHP I am familiar with the typical function syntax:
function name() {return;}
which from what I understand works the same in JS.
Then I decide I want to attempt to use the YUI 3 framework for a small project to continue learning and come across this...YUI Global Object
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
As far as I understand this is using the 'use' function of the YUI() object, passing 'node' to the 'use' function....but then what...why is it declaring a function within another function call?
Could someone please explain the syntax being used here?
Also a good reference that explains JavaScript general syntax's similar to php.net would also be beneficial.
Thanks for your help.
Its an anonymous function. Its considered a callback.
In PHP 4 and early versions of PHP 5 you might see something like this:
PHP
function callback($var){
...
}
array_filter( $array, "callback" );
In later versions of PHP 5 you can define them as anonymous functions inline.
So, in JavaScript, the old version would look like this:
JavaScript
function use_callback(Y){
Y.Node.get('#demo');
}
YUI().use('node', use_callback);
But by defining an inline anonymous function, you can save the extra clutter and defined function:
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
Both those functions are equivalent.
In javascript, functions can be passed around as variables. So, here's some other ways that the YUI code could have been written
//original
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
//more traditional "global function"
function useNode(Y) {
Y.Node.get('#demo');
}
YUI().use('node', useNode);
//local callback function
var myUseNode = function(Y) {
Y.Node.get('#demo');
}
YUI().use('node', myUseNode);
edit As for the second half of your question, you could write what I know about PHP on a postage stamp, so I can't help you there, sorry :-)
This is constructing an anonymous function, and then passing the function itself in as an argument to use. The use method will then call your anonymous function with a value, which in your function will be called Y, which contains the modules that you asked for in the previous arguments to use.
This is essentially equivalent to the following, which passes myFunction in as a callback to YUI().use, except that the anonymous function doesn't have a name:
function myFunction(Y) {
Y.Node.get('#demo');
}
YUI().use('node', myFunction);
This pattern is used because JavaScript doesn't have any kind of explicit notion of namespaces or modules. They can be emulated, however, by using the scope of a function to act as a sort of namespace. In this case, YUI().use will construct an object that has all of the functionality that you request, and pass that object in to the function you provide, so you can use that Y object to call methods that you have imported.
For a good online reference on JavaScript syntax and methods, I like to use the Mozilla Developer Center documentation. In particular, they have good references on JavaScript and the DOM. As it is part of the Mozilla project, they focus on the methods and syntax supported by Gecko (the rendering engine of Firefox), but they usually include compatibility notes to mention what is portable and what is specific to Gecko.
For your question, I would recommend reading the MDC documentation on functions and function scope. Sadly, the MDC doesn't usually come up on top on a Google search; instead, you get W3Schools, which tends to be lower quality and have more ads. I've found it useful to always prefix my searches for anything about JavaScript or the DOM with "mdc" in order to get the MDC documentation; so, for instance, to find that link, I searched for mdc function, and found what I needed.
In JavaScript, functions are objects. In that case, they are passing in an object as the second parameter value (and defining it inline).
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
is the same as this:
var xxx = function(Y) {
Y.Node.get('#demo');
};
YUI().use('node', xxx);
It is an anonymous function (akin to lambda function) declaration.
YUI().use('node', function(Y) {
Y.Node.get('#demo');
})
In Javascript, functions are 1st class citizens - they are objects like any other; hence, they can be passed as parameter.
What is being shown is what is known as an anonymous function that is being passed as an argument to a function. I don't think PHP has first-class functions like this, so I have no idea how to explain the syntax in terms of that (I also don't do much with PHP, so..)
Here is my example code:
function something_random(a) {
alert("the type of a is ... " + typeof(a));
if (typeof(a) === 'function') {
a();
}
}
Now with this function in mind, you can plug this into Firebug or something similar and run the following code:
something_random(function () {
alert("This is a test.");
});
Something interesting will happen here - you will get two alerts. One should say "the type of a is... function" and the other should say "this is a test." This is because in JavaScript - as well as some other languages - functions are treated just like objects (well, they technically are objects.)
You can throw around functions all day if you like - they are just like numbers, arrays, and so on.
Something interesting can also happen. You can also pass arguments into anonymous functions, which is something that jQuery does quite a bit (except it uses call, but we won't go there.) This is where you get the special things like where you put function(d) {} in a code.
Hope this helps.