I have always seen code like this:
(function(){
//code here
})();
How does this code work? Which function receives which parameters?
(function(factory){
//code here
}(function($){
//other code here
}));
function($){
//other code here
}
This block is passed as a parameter to the outer IIFE. It might be clearer to write it like this:
var factoryDef = function($) { ... };
(function(factory) {
// this is the outer IIFE
var someVar = {};
// you can call:
factory(someVar);
// the previous line calls factoryDef with param someVar
}(factoryDef));
So factory(someVar) is the same as factoryDef({}); the latter is simply the value of factory (which is the function factoryDef) called with the value of someVar (which is {}.)
Does that make sense?
Let's dissect:
Another way to look at this is:
Starts with an anonymous function declaration assigning within the function, the first parameter to be passed, the variable name "factory",
Then the anonymous function is immediately invoked, so far so good, often called IIFE, (or in this case D.C. calls "dog balls" ;) ).
Here's a twist, within the immediate invoking of the outer-most function another anonymous function is declared and passed as an argument. This, of course is referred to as "factory" within the outer-most function. And,
This inner-most anonymous function has as a named parameter "$". So I must anticipate the outer most function, when calling "factory", the inner-most function, will pass something to it which will be referred to as "$" in the inner-most function. For example: factory(jQuery);.
Actually when reading code I think it's best to start at the end and inner. So here the first thing I look at is the function with the "$". Looks like an anonymous function declaration. And it happens to be instantiated in a function execution. Moving out and left now. The function that is being immediately executed is also an anonymous function, not a problem because it's only called once and it's execution is built it. And our inner-most anonymous function get's a name in the outer-most function declaration. Finally wrapping the whole deal in parentheses is necessary to put the anonymous function in an expression context. If the first thing on the line is the word "function" then the function is in declaration context and the Javascript parser won't allow it to be immediately invoked. Oops.
Even more stretched out looks like:
var innerMost = function($) { console.log($); };
var outerMost = function(factory) {
var kaChing = 'baLing';
factory(kaChing);
};
outerMost(innerMost);
Voilà!
.
Fiddle with this: http://jsfiddle.net/xFnP7/1/
Much more here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/
Related
Code:
var funcExpression = function(){
alert("function expression");
}();
(function declarFunc(){
alert("declared func");
})();
The result is the function Expression is run first resulting in the alert "function expression" and the declared function is run second "declared func".
I know that during the hoisting process, declared functions are hoisted up entirely within their container and loaded into memory. Function expressions, however are not hoisted: they stay in the same place and are not loaded into memory until runtime(though the variable that points to the function expression is hoisted up and set to Undefined. (Please correct me if I have this concept wrong)
Since, the declared function is hoisted up above the function expression assignment, I would expect thus that the declared function is executed first: resulting in the alert "declared func" and then the function expression is executed afterwards: resulting in the second alert of "function expression".
However: it doesn't do what I expect. Thus, it seems like it has something to do with the immediate invocations of both the functions. Maybe the immediate invocations stay in the same order? Maybe after the hoisting process the code really looks like this:
var funcExpression = Undefined;
(function declarFunc(){
alert("declared func");
})
funcExpression = function(){
alert("function expression");
}();
(); // this executes declarFunc. Maybe declarFunc is hoisted up
// but the invoking part stays in the same place?
Solution after feedback and additional research
The answer is that BOTH of those functions are function expressions:
Code:
var funcExpression = function(){
alert("function expression");
}();
(function declarFunc(){
alert("declared func");
})();
so declareFunc() looks like a declared function, but since it is wrapped in parenthesis like that, it transforms it into a named function expression. The parenthesis following immediately evokes this function expression.
I was having trouble showing what the code looks like after the hoisting process because (function declarFunc(){...})() transforms into a named function expression due to those wrapping parenthesis. What this means is that outside of this named functions scope, we have no way to call it.
Example: If after these functions I did declarFunc() it will return with the error: ReferenceError: Can't find variable: declarFunc.
If we did want to make it possible to run this function expression then we would want to assign the function expression to a variable:
var foo = function declarFunc(){
alert("declared func");
};
Note: If we look at the console we will see that console.log(foo()) will return undefined, but the actions of the function will still take place. Just know that if no return statement is specified, then it implicitly returns undefined.
And now we can call on that function as many times as we would like with foo().
Can somebody explain me what (this) means at the end of the following code:
var a=(function(_this){
return function() {
//do something
return smth;
};
})(this);
What is the sense of such coding?
Going forward, what does the following code do, when placed in .js file and invoked by html tag?
(function() {
Emitter=(function(){
function Emitter() {}
...
return Emitter;
})();
A=(function(_super){...})(Emitter);
}).call(this);
how to instantiate object A from outside the js file?
This is a self-executing function, which is used to save a reference to "this" through the function's closure. It is used to hold on to the reference to "this" at the function's first execution time.
You can also use Function.prototype.bind() to achieve a similar result of saving a reference to "this":
MDN - Bind
This whole structure is a means of saving the current value of this so that a function call later on can use it.
That could all be done also with .bind() like this which (if you understand what .bind() does might be easier to follow):
function myFunc(_this) {
// do something
}
var a = myFunc.bind(null, this);
Here are the various steps in what happens in the code you've shown:
this will have a value from the surrounding context when this code is originally executed (which you don't show). It is being passed into a self-executing function as an argument often referred to as an IIFE (immediately invoked function expression) which is just a function call that happens immediately inline as the code is initially run.
Within that function it is given an argument name of _this.
When that function executes, it returns another function. The body of that inner function also has access to _this.
When that inner function is returned, it is assigned to the variable a.
The upshot of all this is that one can call a() and the internals of that function, when it executes will be able to access _this which contains the value of the original this.
So, it's essentially a means of creating a function that when executed will have access to the original value of this even though the context will have changed when a() is later called. So, its essentially saving the value of this for a specific function to use later.
More detail would require more context about what is going on inside that internal function, what the this value was in the original context and how a() is used later.
This is one particular use of an IIFE. They have many other uses.
Based on some code in a lecture by Doug Crockford, I've created this.
var isAlphaUser = (function() {
alert("Forming Alpha User List");
let AlphaUsers = {
1234: true,
5678: true
};
return function(id){
alert("Checking Alpha Users:",id);
return AlphaUsers[id];};
}());
alert("starting");
alert(isAlphaUser(1234));
alert(isAlphaUser(5678));
alert(isAlphaUser(3456));
which gives me this:
Forming Alpha User List
starting
Checking Alpha Users: 1234
true
Checking Alpha Users: 5678
true
Checking Alpha Users: 3456
undefined
Which is quite cool, as it does the expensive setup once only, and every further call is a cheap check.
However, I can't decipher the code that does this. Specifically, I can't understand why I need the "()" at the end of the function declaration.
Can somebody explain how this syntax is working?
() calls a function. function() { } defines a function. Appending () right after immediately calls it1, and the result (also an anonymous function) is assigned to isAlphaUser.
The function() { ... }() pattern is frequently used to isolate variables to an inner scope, so those variables don't become part of the global scope.
In this case, this is what happens:
An anonymous function is run, defining a variable AlphaUsers inside that scope.
That function returns another function that takes 1 parameter. This function is a closure to which the AlphaUsers variable becomes bound (in other words, available). This function checks if the parameter passed in is contained in AlphaUsers (actually, it returns the item at that index, which is just a boolean).
The return value is assigned to a variable isAlphaUser.
Since isAlphaUser is now a function, it can be called to see if the parameter is contained in the AlphaUsers variable, but no direct access to AlphaUsers is available in the global scope (it become a sort of private variable).
1 — Note: As cwolves mentioned in the comments, beware that while () appended directly after the } works in this case, it is only because in this case the function definition is a function expression. If function is the first word on the line, the line becomes a function declaration, and that is all that line can do, the function is not anonymous (it will require a name, otherwise it's a syntax error) and cannot be called immediately inline. See Function Declarations vs. Function Expressions for more info.
The () at the end of the code is separate from the closure issue. By wrapping your function in parens and adding the () at the end you are creating an anonymous function that is run immediately with whatever arguments you pass into ().
Specifically, I can't understand why I need the "()" at the end of the
function declaration.
It creates self-invoking function, in other words, the function is executed as soon as it is parsed.
It is basically same thing when you call a function by suffixing it with () like:
myfunc(); // call this func
The top-level anonymous function returns the function that the isAlphasUser varaible refers to.
You need to call the top-level function, to get the inner-function reference.
Think of it like this, the outer anonymous function is a function factory, i.e., it returns a function.
In order to use any function (even one that returns a function) you must call it.
Now, I usually call a function (that requires no arguments) with () like this:
myFunction(); //there's empty parens
Except in jQuery calls where I can get away with:
$('#foo').bind('click', myFunction); //no parens
Fine. But recently I saw this comment here on SO:
"Consider using setTimeout(monitor, 100); instead of setTimeout('monitor()', 100);. Eval is evil :)"
Yikes! Are we really eval()-ing a string here? I guess I don't really understand the significance and implications of 'calling' a function. What are the real rules about calling and referring to functions?
In JavaScript functions are first-class objects. That means you can pass functions around as parameters to a function, or treat them as variables in general.
Let's say we are talking about a function hello,
function hello() {
alert('yo');
}
When we simply write
hello
we are referring to the function which doesn't execute it's contents. But when we add the parens () after the function name,
hello()
then we are actually calling the function which will alert "yo" on the screen.
The bind method in jQuery accepts the type of event (string) and a function as its arguments. In your example, you are passing the type - "click" and the actual function as an argument.
Have you seen Inception? Consider this contrived example which might make things clearer. Since functions are first-class objects in JavaScript, we can pass and return a function from within a function. So let's create a function that returns a function when invoked, and the returned function also returns another function when invoked.
function reality() {
return function() {
return function() {
alert('in a Limbo');
}
};
}
Here reality is a function, reality() is a function, and reality()() is a function as well. However reality()()() is not a function, but simply undefined as we are not returning a function (we aren't returning anything) from the innermost function.
So for the reality function example, you could have passed any of the following to jQuery's bind.
$('#foo').bind('click', reality);
$('#foo').bind('click', reality());
$('#foo').bind('click', reality()());
Your jQuery bind example is similar to setTimeout(monitor, 100);, you are passing a reference of a function object as an argument.
Passing a string to the setTimeout/setInterval methods should be avoided for the same reasons you should avoid eval and the Function constructor when it is unnecessary.
The code passed as a string will be evaluated and run in the global execution context, which can give you "scope issues", consider the following example:
// a global function
var f = function () {
alert('global');
};
(function () {
// a local function
var f = function() {
alert('local');
};
setTimeout('f()', 100); // will alert "global"
setTimeout(f, 100); // will alert "local"
})();
The first setTimeout call in the above example, will execute the global f function, because the evaluated code has no access to the local lexical scope of the anonymous function.
If you pass the reference of a function object to the setTimeout method -like in the second setTimeout call- the exact same function you refer in the current scope will be executed.
You are not doing the same thing in your jQuery example as in the second setTimeout example - in your code you are passing the function and binding the click event.
In the first setTimout example, the monitor function is passed in and can be invoked directly, in the second, the sting monitor() is passed in and needs to be evaled.
When passing a function around, you use the function name. When invoking it, you need to use the ().
Eval will invoke what is passed in, so a () is required for a successful function invocation.
First of all, "()" is not part of the function name.
It is syntax used to make function calls.
First, you bind a function to an identifier name by either using a function declaration:
function x() {
return "blah";
}
... or by using a function expression:
var x = function() {
return "blah";
};
Now, whenever you want to run this function, you use the parens:
x();
The setTimeout function accepts both and identifier to a function, or a string as the first argument...
setTimeout(x, 1000);
setTimeout("x()", 1000);
If you supply an identifier, then it will get called as a function.
If you supply an string, than it will be evaluated (executed).
The first method (supplying an identifier) is preferred ...
I'm hoping someone can explain the following usage of JavaScript.
I have a page with a script that looks like this:
(function($){
// code
// and stuff
})(jQuery);
I'm trying to understand what this code does, specifically:
The opening parenthesis at the start
The usage of the $ symbol
The jQuery in parentheses at the end
thanks!
This is an anonymous function.
The specific example you provide is usually used when jQuery (which uses the "$") is conflicting with another library (prototype also uses "$").
What this does is say that whenever "$" is used within the function, it is to reference the jQuery object.
Normal:
$("foo").doStuff()
Conflict avoidance:
jQuery("foo").doStuff()
Using anonymous function to avoid conflict:
(function($){
$("foo").doStuff();
})(jQuery)
At the highest level, it is declaring a function and invoking it in the same statement.
Let's break it down into component parts:
First, we can use $ as an argument/variable name in a function, just like anything else:
function foo($)
{
alert($);
}
foo('hi'); //alerts 'hi'
Second, we can assign a function to a variable:
var foo = function($) {
alert($);
}
foo('hi'); //alerts 'hi'
Finally, we don't have to give functions names - we can just declare them. We wrap them in parenthesis to encapsulate the entire function declaration as a var, which we then call (just like above):
(function($) {
alert($);
})('hi');
In your case, jQuery is some object being passed into the function as the $ parameter. Probably the jQuery library root object, so you can call functions on it.
The parenthesis wrap the anonymous function so it can be called right away with the parameter being a reference to jQuery
$ is a valid variable name in JavaScript, so many frameworks use it for brevity. By including it here as the function argument, you're saying that you want to use $ as an alias for jQuery. This lets you keep your code as short as possible and save your user's bandwidth.
Answered in the first part - you're sending a reference to the jQuery object/framework to your anonymous function.
Briefly:
This declares an anonymous function which accepts one argument, referred to by the local variable name of $, and then immediately calls the function passing as the first argument the jQuery object.
Less briefly:
In javascript a function is declared like this:
function foo(arg1, arg2){
}
Later the function foo can be called:
foo("arg 1", "arg 2");
But in javascript functions are first class citizens; you may, if you choose, store a function in a variable. When doing this the variable name is the function name, so you write it like this:
var foo = function(arg1, arg2){
};
The trailing semicolon is required because a variable declaration (and assignment) is a statement. Later, the function foo can be called:
foo("arg 1", "arg 2");
The advantage here is that you can pass the function to another function, or store it in an array, or whatever. Functions of this sort are called anonymous functions (because they have no function name as such).
Inside the anonymous function foo, as seen above, you can declare local variables which remain withing the scope of that function and do not exist in the scope in which the function was declared. For example, the local arg1 and arg2 variables don't exist in the scope of the variable foo (but they do exist within the anonymous function stored in foo).
This trick allows us to create a private block in which we control what things are named without worrying about stomping over someone else's namespace.
You could write the example you provided as follows:
var foo = function($){
};
fn(jQuery);
Which is the same thing, but has that ugly intermediate variable. What may not be obvious is that the declaration of the anonymous function "returns" a function reference which can be invoked later... or at the same time, merely by adding the function call syntax of ().
What the code is doing is defining an anonymous function, which creates a private scope, and then immediately calling it without storing in a variable. Like this:
function(arg1){
}("arg 1");
I am not entirely sure why there's an extra set of parentheses arroudn the anonymous function definition, but they at least make the code a little more readable/logical. You are merely passing an argument to the result of the parenthetical expression, which happens to be a function:
(function(arg1){
})("arg 1");
All of tis allows jQuery to have a globally-scoped variable named jQuery, but also allows you the user to use the shorthand of $ without conflicting with other javascript frameworks which use the same name for other things.
Let’s first look at the inner function declaration:
function($){
// code
// and stuff
}
This is an anonymouse function declaration with one parameter named $. That function is then wrapped in parenthesis and called by appending (jQuery) to it with jQuery as parameter.