Difference between a named IIFE and calling a name function immediately? - javascript

Is there any difference between and IIFE
(function foo () {
var var_of_concern;
}());
and a plain function
function foo () {
var var_of_concern;
}
foo();
The caveat that concerned me, was if I pass nothing out of either the IIFE or the function, will the IIFE keep the memory alive longer?

The opposite, though it's probably not a serious concern.
The two are syntactically not the same. The second declares a function and binds it to the local symbol "foo". That function will remain after the function call.
The IIFE form is syntactically a single expression satement. The second form involves two statements, a function declaration statement and an expression statement (the function call).
The way that a function call handles local variable declarations has nothing to do with how the function object came into being. If both functions in your example are the same, then there's no difference to how that space is allocated for the local variables in a function call.
edit — the key syntactic difference is this: the keyword function at the start of a new statement introduces a function declaration statement. That syntactic form does not provide for immediate invocation. That is, this:
function hello() {
// some code
}(); // <---- ERROR
is a syntax error.
When the function keyword appears in any other context (well, any valid context), then it's not a function declaration — it's a function instantiation (or function definition; I'd have to check the spec) expression. These are all things that can be part of an expression in JavaScript:
5
"hello"
false
(2 + 5)
(function() { alert("Hi!"); })
Note that the last example involves parentheses - that's commonly done to "defuse" the "Oh look a function declaration!" behavior of the parser. That opening parenthesis means that the function keyword does not appear at the absolute beginning of the statement, so it's therefore just a function instantiation expression.

Related

Why can I not .bind(this) when a function is directly declared

Given the following:
function x() {
this.abc = 1;
function f1() {
alert(this.abc);
}.bind(this)
var f2 = function b() {
alert(this.abc);
}.bind(this);
}
What I would like is for the "this" of the outer function to be available inside the f1 and f2 functions.
Why is it that VS2013 tells me there's a syntax error with the bind(this) on function f1() ?
There's a difference between a function declaration statement and a function instantiation expression. Both involve the keyword function, but a declaration statement cannot immediately be used as a reference to a function. A function instantiation expression is part of the expression grammar, so it can be used freely in that context as a reference to a function because that's what it evaluates to.
You can of course do this:
(function a() {
}).bind(this);
though without using the return value from .bind() it's not very useful.
If the first token in a statement is function, then you've got a function declaration statement. If the first token is not function, then you've either got another sort of keyword-introduced statement (for, return, var, try, whatever), or else you've got an expression statement. In that expression (or in any expression in another context), your function instantiations are part of the expression grammar and the value can be used as a reference to a function.
Here's another way to think about the problem. Let's pretend that there is only one way to instantiate a function in JavaScript, and that's the function expression. That is, let's pretend that any use of the function keyword means to instantiate a function and return a reference to that function as it's value.
Now, thinking generally about expressions and the things that participate in expressions, the point is to compute some sort of value. When you need the value 5 as part of an expression, you put 5 in its place and that's that. By itself, 5 is a valid expression, so this is not a syntax error:
5;
What does that do, however? It does nothing. Similarly, in our make-believe JavaScript without function declaration statements,
function foo(a, b) {
return a + b;
};
would also do nothing at all. What would happen is simply that the function would be instantiated but thrown away because the value — the reference to the instantiated function — is not saved as the value of a variable or passed to some function or anything else. In this make-believe JavaScript, you'd use
var foo = function(a, b) {
return a + b;
};
all the time.
The language design does have function declaration statements, however. As a simplifying approach, the language just recognizes a statement whose first token is the keyword function as a completely different sort of statement than an expression statement that happens to contain a function instantiation. There are other ways in which the problem could have been addressed (such as the use of a different keyword), but I suspect that there'd still be confusion.
Note that there are JavaScript programmers who strongly prefer using var declarations for functions. It's a matter of style really.

Any difference between f() and (f())?

Any difference between
var myfunc = (function () { return function () { ... } }());
and
var myfunc = function () { return function () { ... } }();
Is it just a matter of style or is there more to the surrounding () in the first form?
Nope. Or at least not in your example.
The outer parens only matter when the function keyword would be the first token in a statement.
// cool
var foo = function(){}();
var foo = (function(){}());
// also cool
(function(){}());
// not cool, syntax error
// parsed as function statement, expects function name which is missing
function(){}();
// also not cool, syntax error
// declares a function, but can't be executed immediately
function foo(){}();
When function is the first token in a statement, it's a function declaration (think named function), which behaves slightly differently than function in all other contexts. That leading paren forces the parses to treat it like a function expression (think anonymous function) instead, which allows immediate execution.
See: What is the difference between a function expression vs declaration in JavaScript?
If you start the line or statement with something else, like variable declaration, it technically doesn't matter at all.
No difference, though Crockford advises the use of the former, to ascertain that it's being treated as a function expression.
For more info, read these:
Immediately-Invoked Function Expression (IIFE)
Named function expressions demystified
There's no technical difference, It's just an idiomatic style used for readability to signal at the start that it's a self-invoking function.
no difference, it is just a matter of style. Both are executed functions and they return whatever they return in the variable and they are returning a function. check this out
the purpose is to avoid the global scope, adding the var myfunc = in front of (function (){ return function(){}}()); essentially defeats the purpose
compare the two
(function(){...do something...}());
this function is ran in a local scope, which is inside the parentheses.
var myfunc = function(){};
this function is ran on the global scope.
why not this way, because you can get your self into naming conflicts with other methods and var as well as plugin's named var and it can hinder your applications performance with the var being saved on the global scope.
I perfer
(function() {})();

Is this an anonymous function?

In the first snippet below, based on my understanding I am creating a function and assigning it to a variable. But does that mean the function will take that name of the variable ?
var aFunc = function(){};
I know this is named function.
function bFunc(){};
So, first of all we have to clarify the main difference between the two functions you wrote.
This one:
var aFunc = function(){};
is a function expression. Where this one:
function bFunc(){};
is a function declaration.
In a function expression you're using the function operator to defines a function inside an expression.
When you declare a function you're using the function statement.
At the beginning it can be confusing because they're really similar, however function declaration and function expression behaves differently. First of all, you can't declare a function that is anonymous: if you're using a function statement, the name is mandatory.
So only functions defined with the function operator can be anonymous:
var aFunc = function(){};
That's an anonymous function. In some browsers you can actually print the function's name and see by yourself:
console.log(aFunc.name);
(Notice that this is not standard yet, but there is a proposal)
But it doesn't means that functions declared with the function operator have to be anonymous. For instance:
var aFunc = function myFunction() {};
It's a named function. However, that's still different from having a function declaration like that:
function myFunction() {};
var aFunc = myFunction;
Why? Because in case of function expression, you don't declare a myFunction function in the scope:
var aFunc = function myFunction() {};
console.log(typeof myFunction) // undefined, unless some bugs
So what's the point to give a name to a function expression? The answer is: to have access from that function from the function's body itself, without pollute the scope. Imaging for instance you want to add an event listener to a DOM node, but execute the listener only once:
document.body.addEventListener("click", function onclick() {
// do something
document.body.removeEventListener("click", onclick, false);
}, false);
So you don't pollute the scope with a lot of functions that you use only for purpose like that ones, and you can still have access to the function from the function's body. That's especially useful in ES5 where arguments.callee is deprecated, and for recursion.
Another difference between function expression is that you can invoke them immediately, but you can't do that for function declaration. So, for instance:
function() {
console.log('foo');
}();
Will throw an exception, because the engine can't understand if it's a function declaration or a function expression. But if you force the engine to look at it as an expression:
!function() {
console.log('foo');
}();
// or
(function(){
console.log('foo');
}());
// etc, there are a lot of ways
Here we are: JS understand is an expression, therefore threats the function as an operator and not as a statement. And you obtain the IIFE (Immediately-Invoked Function Expression), that are useful in a lot of scenarios, specially where you want to isolate code.
So, back to you question, why the name of this function:
var aFunc = function(){};
is not aFunc?
Because, it's an expression. So the value knows nothing about the assignment on the left. It's like having:
var aFunc = -3;
Where the - is the Unary Negation operation and the 3 is the value: they knows nothing about aFunc, right? It's exactly the same with function expression, where function is the operator, and (){} is the value.
No.
In the first example you are creating an anonymous function and then assigning it to "aFunc"
In the second example you declare a function and call it bFunc.
The most notable difference between the two is that you can't call "aFunc" until after the line where you assign it.
No, the function will not "take the name of the variable". The variable will hold a reference to an anonymous function. The function itself is still anonymous.
Note that this makes little difference in the end though, this function reference can be treated exactly the same as any regular named function once it's assigned. In fact, it makes so little difference, a named function can be treated like a variable holding a function reference too:
function foo() { }
foo();
foo = 'bar';
alert(foo); // bar
The term "anonymous function" is jargon, so likely what it means will change over time. There is no specification that states what it is, so it can be whatever you want it to be. And whatever you decide will likely be disputed by someone else. Jargon is like that (look up the word "trunking", a common jargon term in telephony).
Strictly, there are function declarations where the name is mandatory, e.g.
function foo() {
...
}
and function expressions where the name is optional. If the name is missing, e.g.:
var x = function () {
...
};
then that, to me, is an anonymous function. If it has a name, e.g.
var x = function foo() {
...
};
then it's a named function expression (and not an anonymous function). From my perspective, any function expression without an optional name is an anonymous function. There are many uses for function expressions, e.g.
// assignment to a variable
var x = function() {...}
// pass as a parameter
foo(function(){...})
// immediately executed and pass the result
foo( (function(){...}()) )
and so on. So in the OP, the right hand side of the assignment is a function expression with no name so to me, that's an anonymous function. The fact that it's then assigned to an identifier doesn't suddenly make it a named function expression.
Others may differ of course.
Incidentally, the results of:
function foo(){}
and
var foo = function(){};
are practically indistinguishable, the main difference is when the functions are created.
No it is not. The right hand side of your first statement is a Function Expression. It is anonymous as long as you don't assign it to a variable.
After you have assigned it, you can use it as a declared function.
See more details about function declarations in this question

Purpose of the outer extra parenthese on JavaScript closure function [duplicate]

This question already has answers here:
JavaScript - self-executing anonymous functions and callback
(2 answers)
Closed 9 years ago.
What is the purpose of the outer extra parentheses on the below JavaScript closure function? I have been told in other posts that they are not strictly necessary, but they're a convention to make it clear that the result of the function is being passed, not the function itself. The below quote from http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
, however, conflicts. Which is correct?
Notice the () around the anonymous function. This is required by the
language, since statements that begin with the token function are
always considered to be function declarations. Including () creates a
function expression instead.
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());
I think that different engines have different ways of interpreting
function(){...}();
so the most popular and accepted way to make it clear, to all engines, is to group the code in parentheses.
(function(){...}());
At the same time, what you quoted makes a very interesting point. A function expression might go:
var f = function() {...}
Whereas a function declaration looks like:
function f() {...}
You see how it's easy/convenient for the parser to tell the difference by looking at the first token?
IF TOKEN1 EQ "function": FXN DECLARATION
ELSE: FXN EXPRESSION
But it wouldn't make sense for your (immediately-invoked) function to be a function declaration (it's not going to be re-used, you don't want to have it hoisted, or in the namespace, etc.) so adding some innocuous parentheses is a good way of indicating that it's a function expression.
First of all, I must clear up:
(function () {
}());
is equivalent for
(function () {
})();
and also for (Backbone.js uses it)
(function(){
}).call(this);
Second, if you're going to use it that way, then it's not an anonymous/closure function. its Immediately-Invoked Function expression
it would act as a closure (because it won't be immediately-invoked) if you assign its returned context to a variable. This kinda useful if you need a static class (when properties and methods could be accessed without instantiation). For example:
var stuff = (function(){
// AGAIN: its not an IIFE in this case
function foo() // <- public method
{
alert('Jeeez');
}
return {
foo : foo,
}
})();
stuff.foo(); //Alerts Jeeez
What is the purpose of the outer extra parentheses on the below
JavaScript closure function?
The purpose isn't usual and quite strange - its all about function arguments.
For example,
(function(window, document){ // <- you see this? 2 "arguments"
alert(arguments.length); // 0!
})();
but if we pass them to that outer parentheses
(function(/* So its not for arguments */ ){
alert(arguments.length); // 2
})(window, document); // <- Instead we pass arguments here
The extra surrounding parentheses disambiguate a function expression from a regular function declaration.
Though the extra parentheses are standard practice, the same thing can be achieved by doing this instead:
void function() {
// do stuff
}();
Or, even:
+function() {
// do stuff
}();
Though, out of these two alternatives, I prefer the void notation because in most cases we don't really care about the return value of an immediate invocation.
Other places where the parentheses aren't required is when an expression is expected:
setTimeout(function() {
return function() {
alert('hello');
}
}(), 1000);
They are necessary because the parser goes in the function declaration mode when it sees
function
in a statement context.
After function token, it is expecting a name for the function because a function declaration must include a name for the function. But instead of a name it sees ( instead, so it's a syntax error.
I think, it could backtrack and unambiguously just treat it as a function expression but it doesn't.
var module = XXX
In the above, XXX is in expression context, if a function appears there, it is treated as a start of a function expression. Function expressions don't have to have
a name for the function, so it's not a syntax error to have ( appear right after function.
So you can write:
var module = function(){}();
But not
function(){}()
You can use many tricks to make the above an expression:
(XXX)
!XXX
~XXX
+XXX
//This doesn't work however:
{YYY} //the braces are delimiting a block, and inside block you start in
//a statement context
XXX is in expression context because it's enclosed by parenthesis or is following a unary operator, therefore any function substituted for XXX is a function expression.

Javascript: explain this syntax to me

JS newbie here, I've been looking through some code recently which uses syntax I'm not too familiar with. Here's an example, followed by my questions:
function Group(args) {
this.showItem = showItem;
function showItem(args) {
...
}
}
var group = new Group (args);
Questions:
As I understand it creating function Group and then instantiating via group = new Group is essentially prototypal equivalent of defining a class and then instantiating an object of that class. Is that correct?
Regarding the properties (methods?) of Group, what is the above syntax for showItem called? Why not just define it like:
this.showItem = function(args){...};
Would changing the code to the above change any different behavior?
If you did define it as above, what is that syntax called?
The Group function is being used as a constructor; your intuition is basically correct.
There is no good reason not to use an anonymous function expression like this.showItem = function(args){...};, unless you wanted to reuse the local variable showItem.
I'm not sure which syntax you mean. The function(args){...} is an anonymous function expression, and the this.showItem is referring to a member of the object this. Taken all together, I suppose you could call it "setting a member function of an object".
Bonus tip (which maybe you already knew?): the reason you can use showItem before its definition is due to function hoisting.
EDIT:
You seem to be asking about function expressions versus function declarations as well as named versus anonymous functions. The primary differences are:
Function declarations always stand on their own. They are never part of another operation, e.g. assignment. Your first example uses the function declaration function showItem(args) {...}. Function expressions are used as an expression in some operation (e.g., assignment, passed as an argument, etc.). Your second case uses a function expression.
Function declarations are hoisted to the top of the current function scope, so showItem in your first case is defined and contains the function when you use it in your assignment operation. Function expressions are not hoisted.
Function declarations are always named. Function expressions may be named or anonymous. When a function is defined with a name, that name is accessible as the name property of the function object. A function's name is immutable and independent of any variables that hold a reference to the function. Also, code inside the function body can refer to the function by its name as a local variable (which is sometimes useful for recursion inside named function expressions).
To review:
Function definition: function showItems(args){...};
Anonymous function expression: this.showItems = function(args){...};
Named function expression: this.showItems = function showItemsName(args){...};
In the first case, there is a local variable called showItems defined and the definition of showItems is hoisted to the top. The difference between the latter two cases is that this.showItems.name will be "showItemsName" for the third case and undefined for the second. Also, showItemsName will be a local variable within the function body of the third function that holds a reference to the function object.
The Group function is used as a constructor. However, the way this is done is a bit inefficient. What this code is doing is creating a new function and attaching it to the constructed object. He may be doing this because he wants to create a closure (i.e. use a variable only present in the namespace of the constructor), but absent that reason it's better to do this:
function Group(args){}
Group.prototype.showItem = function(args) {};
This way the same showItem function is shared among all objects constructed by Group via the prototype chain.
The benefit of using the original code vs an anonymous function is that the function has a name--this is a great help in debugging because reading a traceback full of anonymous function calls is no fun! To expand, there are three types of things that use the function keyword:
Function declarations When at the top level of a program or a function (i.e., of something that creates/has its own namespace), you may declare a function with a name. (The name stays with the function object throughout the program and will appear in tracebacks.) This is function showItem(args) {} in your example. (Note that this is only a function declaration at the top level of a file or function. There's a very similar thing I'll get to last.) By convention most people seem to omit semicolons after these.
Function expressions When part of an expression (such as assignment, return, etc), it is a function expression. The identifier part of the function expression is optional, so these are both function expressions:
var myfunc1 = function(){};
var myfunc2 = function MyFunctionName(){};
The second form is called a "named function expression". The great benefit of using this form is that MyFunctionName is no longer an anonymous function--this name will be attached to the function and will show up in tracebacks (for example). However there is a very serious bug in JScript (IE <= 8) that makes using these problematic. Read the article I linked above for details.
Finally, there is a common extension syntax called function statements. These look exactly like function declarations, except they are not top level! For example:
function() {
function foo(){} // function declaration
if (1) {
function bar(){} // function STATEMENT--not standard JS!
}
}
You should not rely on this extension, but should do this instead:
function() {
var bar;
if (1) {
bar = function bar(){};
}
}
this.showItem = function(){} would be called a "function expression in an assignment", and the original code is just using a "function declaration".

Categories

Resources