Javascript: difference between the different forms of functions - javascript

# Version A - Function Declaration Statement
// Some JavaScript code
function a() {
// code within function
}
//Some more JavaScript code
# Version B - Function Expression
// Some JavaScript code
var b = function () {
// code within function
};
// Some more JavaScript code
I've been reading JavaScript: The Definitive Guide and I wanted to make sure I'm understanding how these 2 versions are being processed by JavaScript. I'll explain my understanding for each version below:
Version A
JavaScript scans the script at the global scope and identifies all variable and function definitions and hoists them to the top. Variable assignments and function evaluations won't happen yet.
For the function a(), JavaScript will then package up the global context and associate it with the scope chain of the function. At this point, the function a() will know all the variable and function definitions in Step 1.
JavaScript does NOT evaluate the function a() and therefore doesn't know anything about the local context within the function. This will remain true until the function is invoked.
Version B
Same as step 1 from above - JavaScript scans the script at the global scope and identifies all variable and function definitions and hoists them to the top. Because the variable b is hoisted to the top, the script is equivalent to this:
var b;
// Some JavaScript code
b = function (){ /* code within function */ };
// Some more JavaScript code
When JavaScript comes to variable b's assignment, it sees that an anonymous function object is being defined. When JavaScript defines the function, it will package up the context in which the function is defined (in this case, it's the global context) and associate it with the scope chain of the function. At this point, the anonymous function will know all the variable and function definitions in Step 1 which includes var b being undefined.
Because JavaScript sees that the function is being used as an expression in a variable assignment, it will evaluate the function expression. When it evaluates the function expression, it will again hoist all variable and function definitions within the local scope to the top and if there are any function declaration statements within this function expression, it'll package this local context and add it to the scope chain of this function.
A function object is returned when the function is evaluated and then the function object is assigned to var b.
If you could comment on each of the versions and let me know if my understanding is accurate, that'd be great.

Theory is nice, but in real life browsers use their own dialect (as a result of using their own engine and added browser-candy).
For instance IE doesn't care that your script-tag specifies 'text/javascript'. It'll use its own JScript anyway.
So (to devise a polyglot EcmaScript dialect) it helps to also understand that the theory might not work in the same manner in real life.
For example, a Named function expression is treated as BOTH — function declaration AND function expression in IE(JScript):
typeof g; // "function"
var f = function g(){};
See this link for some of those examples:
http://kangax.github.com/nfe/#jscript-bugs
Actually, here is a rather complete and 'semi-official' (by Pratap Lakshman from MS) overview of JScript deviations from ES3:
http://wiki.ecmascript.org/lib/exe/fetch.php?media=resources:jscriptdeviationsfromes3.pdf
Lastly I'd want to point to this very helpful video where Douglas Crockford explains things some more thorough in 'Crockford on JavaScript - Act III: Function the Ultimate':
http://youtu.be/ya4UHuXNygM
Hope this helps!

Related

What is the purpose of var foo = (function() {

I came across following code. Can someone explain it to me? I'm not sure how it'll be executed? Is there any specific reason to write it like this?
var foo = (function() {
// ...bunch of code
return function(param1) {
// ...bunch of code
return var1;
}
})();
EDIT: I know that the outer part (...)();, is executed immediately. What I'm not sure is why it is assigned to variable foo. I guess when the IIFE is executed it'll only execute the return ... inner code. But when the code inside that inner function ... is executed? When the line return var1 is executed? I hope now it is clear as water
What you're seeing is a JS idiom called Immediately-invoked function expression. Extracted from Wikipedia:
An immediately-invoked function expression (or IIFE, pronounced "iffy"1) is a JavaScript programming language idiom which produces a lexical scope using JavaScript's function scoping. Immediately-invoked function expressions can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and simultaneously allow public access to methods while retaining privacy for variables defined within the function. This concept has been referred to as a self-executing anonymous function,[2] but Ben Alman introduced the term IIFE as a more semantically accurate term for the idiom, shortly after its discussion arose on comp.lang.javascript
As can be read in the extract, it's main purpose is mainly to avoid polluting the global namespace though it is also heavily used to take advantage of closure.
UPDATE
In Javascript, functions are first-class objects. This means that they can be passed around like any other object would be. They can also be assigned to variables.
The function you mention is just returning a function (like it could be returning an int or an object literal) that gets assigned to the variable foo. foo then has the reference to the function and can be executed like any normal function would be (i.e foo('a') ).
By the way, a function that returns another function or takes one or more functions as arguments is called higher-order function.
Hope this clarifies things.
The reason would be difficult to guess, but it could be for obfuscation, to avoid plagiarism
The execution will go like:
var foo will receive the result of a function call (the parenthesis after the assignment contain a function declaration, and right after those, the other pair of parenthesis are those function arguments)
that 1st anonymous function will execute the bunch of code, then return what the other function evaluates
the 2nd anonymous function well execute the other bunch of code and finally return var1
ergo: it is the same of executing bunches of code, store the result in var1 and then var foo = var1, simplifying for explanation purpose

Will a simple function declaration form a closure in JavaScript?

Will the following code form a closure?
function f() {}
Does where this function is defined affect the answer?
Yes, it forms a closure.
A closure is the combination of a function reference and the environment where the function is created. The code in the function will always have access to any variables defined in the scope where the function is created, no matter how the function is called.
Example; the function f will always use the variable x even if it is called in a scope where x isn't reachable:
function container() {
var x = 42;
function f() {
document.write(x);
}
return f;
}
var func = container();
func(); // displays 42
//document.write(x); // would give an error as x is not in scope
Yes, it always defines a closure no matter where it is defined. This tutorial has a few illustrative examples.
You create a closure when the function has references to variables in its lexical scope:
var a = 'foo'
function f() {} // no closure
function f() {return a} // closure
If you place a debugger statement inside the function you can see what the closure contains in Chrome devtools. You'll see the first example has nothing, while the second will show a: 'foo'
Because javascript is a special language (see scope, hoisting and more recently the TDZ), depending on how specific you are in your question you might get different answers.
Is it a javascript closure? No. See definition by Mozilla https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Is it captured in a closure (or does it form a closure - the original question)? Depends on optimizations. But most likely yes. See http://dmitrysoshnikov.com/ecmascript/chapter-6-closures/ and more importantly https://en.wikipedia.org/wiki/Closure_%28computer_programming%29
The closure term is used by javascript "evangelists" to identify those functions that would not work correctly if they weren't captured in actual closures - this is the correct way of saying it from a fundamentally operational point of view. And the reason is probably due to a lack of a better term rather than anything else.

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".

Javascript - Do I need to use 'var' when reassigning a variable defined in the function's parameters?

I've found many definitions of the 'var' statement but most of them are incomplete (usually from introductory guides/tutorials). Should I use 'var' if the variable & scope has been declared in the params list?
someFunc = function(someVar)
{
// Is it considered good practice to use 'var', even if it is redundant?
var someVar = cheese;
};
The answer is no, you shouldn’t be doing this. This is actually considered a bad practice!
JS Lint throws the following error when analyzing your code example:
Problem at line 5 character 16: someVar is already defined.
"I've found many definitions of the 'var' statement but most of them are incomplete."
Try this (a bit stuffy but hopefully complete :-) ): The var keyword declares a new variable, binds it to the current lexical scope, & hoists it to the top of said scope. In other words, the variable will not exist outside of the function that declares it & will be declared before any statements are executed inside the function. Function parameters are implicitly bound to that function's scope so do not require the var keyword.
Nope, the order in which names are defined when entering an execution scope is as follows:
function parameters (with value passed or undefined)
special name arguments (with value of arguments if doesn't exist)
function declarations (with body brought along)
variable declarations (with undefined if doesn't exist)
name of current function (with body brought along, if doesn't exist)
This means that in this code, foo refers to the function parameter (which could easily be changed):
function foo(foo) {
var foo;
alert(foo);
}
foo(1); // 1
If you're using a function declaration inside for foo, that body will override all others. Also, note that this means that you can do this:
function foo(arguments) {
alert(arguments);
}
foo(); // undefined
foo(1); // 1
Don't do that.
No. In Javascript, you can mess with the function argument all you want.
Consider this code, which you see all over the Web and which is used to make code work in standard and IE event models:
function someEventHandler(event) {
event= (event) ? event : window.event;
// statements
}

JavaScript scope and closure

I'm trying to wrap my head around closures (there's a joke in there somewhere) and I ran across this:
(function () { /* do cool stuff */ })();
How does this work? What's the purpose of putting the function in parens? Why the empty parens afterwards?
The point of this is that any variables declared in the cool stuff will not be created in global namespace. Any function in javascript will create such a scope. Suppose you have some javascript you want to run. If you do this:
var b = 1;
// stuff using b
And some other code uses b, it will get your left over value. (Or, even worse, if some other code sets b before your code runs, then tries to get its old value later, you'd have changed it in the meantime.)
On the other hand, if you have this code, which declares and then calls the a function:
function a() {
var b = 1;
}
a();
And some other code later on uses b, it will not see your values, since b is local to the function. The problem with this, of course, is that you're still making a global name - "a", in this case. So, we want a function with no name - this is why you get the code you described. It declares a function with no name, and then calls it.
Unfortunately, you can't just say:
function() { ... }()
because this will be parsed as a function declaration statement, and then a syntax error. By wrapping the function declaration in parenthesis, you get a function expression, which can then be called. You call it like any other function expression (like a, above), using the second set of parens. For example, if the function took arguments, you'd pass them there:
(function(a) { ... })(1)
That creates a function, calls it, and discards it.
It might be clearer if you look at it like this:
var throwaway = function(){
// do cool stuff
};
throwaway();
This is done to create a private namespace. Code in the function can have functions and variables without worrying about conflicting with other code loaded in the page.
i just came across this post recently. This type of function definition & call is called self-invoking functions.
(function(){ //code })();
The code inside the function will be executed immediately upon its definition.
That construct means declare an anonymous function and run it immediately. The reason you put your code inside a function body is because the variables you define inside it remain local to the function and not as global variables. However, they will still be visible to the closures defined inside this function.
The parens around the function make it clear that the function is an expression. The parens after are the call to the function.
Notice that the function does not have a name.
One closures approach is to pass variables to the function:
(function($, var_1, var_2) {
// use JQuery, var_1 and var_2 as local variables
})($, var_1, var_2);
Putting the function declaration inside parens creates an expression which evaluates to the anonymous function within. Therefore, the first parenthetical evaluates to a function.
The "empty parens" at the end invoke the defined function, so "//do cool stuff" executes immediately.
This is a way to execute code on-the-fly while also keeping variables out of the global scope.
What is illustrated here, however, has nothing to do with closures - at least not directly. Closures are about maintaining a lexical scope after a parent function has already exited.

Categories

Resources