I would like to know what this means:
(function () {
})();
Is this basically saying document.onload?
It’s an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it’s created.
It has nothing to do with any event-handler for any events (such as document.onload).
Consider the part within the first pair of parentheses: (function(){})();....it is a regular function expression. Then look at the last pair (function(){})();, this is normally added to an expression to call a function; in this case, our prior expression.
This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.
This is why, maybe, you confused this construction with an event-handler for window.onload, because it’s often used as this:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Correction suggested by Guffa:
The function is executed right after it's created, not after it is parsed. The entire script block is parsed before any code in it is executed. Also, parsing code doesn't automatically mean that it's executed, if for example the IIFE is inside a function then it won't be executed until the function is called.
Update
Since this is a pretty popular topic, it's worth mentioning that IIFE's can also be written with ES6's arrow function (like Gajus has pointed out in a comment) :
((foo) => {
// do something with foo here foo
})('foo value')
It's just an anonymous function that is executed right after it's created.
It's just as if you assigned it to a variable, and used it right after, only without the variable:
var f = function () {
};
f();
In jQuery there is a similar construct that you might be thinking of:
$(function(){
});
That is the short form of binding the ready event:
$(document).ready(function(){
});
But the above two constructs are not IIFEs.
An immediately-invoked function expression (IIFE) immediately calls a function. This simply means that the function is executed immediately after the completion of the definition.
Three more common wordings:
// Crockford's preference - parens on the inside
(function() {
console.log('Welcome to the Internet. Please follow me.');
}());
//The OPs example, parentheses on the outside
(function() {
console.log('Welcome to the Internet. Please follow me.');
})();
//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
console.log('Welcome to the Internet. Please follow me.');
}();
If there are no special requirements for its return value, then we can write:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Alternatively, it can be:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
You can even write:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
That construct is called an Immediately Invoked Function Expression (IIFE) which means it gets executed immediately. Think of it as a function getting called automatically when the interpreter reaches that function.
Most Common Use-case:
One of its most common use cases is to limit the scope of a variable made via var. Variables created via var have a scope limited to a function so this construct (which is a function wrapper around certain code) will make sure that your variable scope doesn't leak out of that function.
In following example, count will not be available outside the immediately invoked function i.e. the scope of count will not leak out of the function. You should get a ReferenceError, should you try to access it outside of the immediately invoked function anyway.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
ES6 Alternative (Recommended)
In ES6, we now can have variables created via let and const. Both of them are block-scoped (unlike var which is function-scoped).
Therefore, instead of using that complex construct of IIFE for the use case I mentioned above, you can now write much simpler code to make sure that a variable's scope does not leak out of your desired block.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
In this example, we used let to define count variable which makes count limited to the block of code, we created with the curly brackets {...}.
I call it a “Curly Jail”.
It declares an anonymous function, then calls it:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
That is saying execute immediately.
so if I do:
var val = (function(){
var a = 0; // in the scope of this function
return function(x){
a += x;
return a;
};
})();
alert(val(10)); //10
alert(val(11)); //21
Fiddle: http://jsfiddle.net/maniator/LqvpQ/
Second Example:
var val = (function(){
return 13 + 5;
})();
alert(val); //18
(function () {
})();
This is called IIFE (Immediately Invoked Function Expression). One of the famous JavaScript design patterns, it is the heart and soul of the modern day Module pattern. As the name suggests it executes immediately after it is created. This pattern creates an isolated or private scope of execution.
JavaScript prior to ECMAScript 6 used lexical scoping, so IIFE was used for simulating block scoping. (With ECMAScript 6 block scoping is possible with the introduction of the let and const keywords.)
Reference for issue with lexical scoping
Simulate block scoping with IIFE
The performance benefit of using IIFE’s is the ability to pass commonly used global objects like window, document, etc. as an argument by reducing the scope lookup. (Remember JavaScript looks for properties in local scope and way up the chain until global scope). So accessing global objects in local scope reduces the lookup time like below.
(function (globalObj) {
//Access the globalObj
})(window);
This is an Immediately Invoked Function Expression in Javascript:
To understand IIFE in JS, lets break it down:
Expression: Something that returns a value
Example: Try out following in chrome console. These are expressions in JS.
a = 10
output = 10
(1+3)
output = 4
Function Expression:
Example:
// Function Expression
var greet = function(name){
return 'Namaste' + ' ' + name;
}
greet('Santosh');
How function expression works:
- When JS engine runs for the first time (Execution Context - Create Phase), this function (on the right side of = above) does not get executed or stored in the memory. Variable 'greet' is assigned 'undefined' value by the JS engine.
- During execution (Execution Context - Execute phase), the funtion object is created on the fly (its not executed yet), gets assigned to 'greet' variable and it can be invoked using 'greet('somename')'.
3. Immediately Invoked Funtion Expression:
Example:
// IIFE
var greeting = function(name) {
return 'Namaste' + ' ' + name;
}('Santosh')
console.log(greeting) // Namaste Santosh.
How IIFE works:
- Notice the '()' immediately after the function declaration. Every funtion object has a 'CODE' property attached to it which is callable. And we can call it (or invoke it) using '()' braces.
- So here, during the execution (Execution Context - Execute Phase), the function object is created and its executed at the same time
- So now, the greeting variable, instead of having the funtion object, has its return value ( a string )
Typical usecase of IIFE in JS:
The following IIFE pattern is quite commonly used.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
we are doing two things over here.
a) Wrapping our function expression inside braces (). This goes to tell the syntax parser the whatever placed inside the () is an expression (function expression in this case) and is a valid code.
b) We are invoking this funtion at the same time using the () at the end of it.
So this function gets created and executed at the same time (IIFE).
Important usecase for IIFE:
IIFE keeps our code safe.
- IIFE, being a function, has its own execution context, meaning all the variables created inside it are local to this function and are not shared with the global execution context.
Suppose I've another JS file (test1.js) used in my applicaiton along with iife.js (see below).
// test1.js
var greeting = 'Hello';
// iife.js
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
console.log(greeting) // No collision happens here. It prints 'Hello'.
So IIFE helps us to write safe code where we are not colliding with the global objects unintentionally.
No, this construct just creates a scope for naming. If you break it in parts you can see that you have an external
(...)();
That is a function invocation. Inside the parenthesis you have:
function() {}
That is an anonymous function. Everything that is declared with var inside the construct will be visible only inside the same construct and will not pollute the global namespace.
That is a self-invoking anonymous function.
Check out the W3Schools explanation of a self-invoking function.
Function expressions can be made "self-invoking".
A self-invoking expression is invoked (started) automatically, without
being called.
Function expressions will execute automatically if the expression is
followed by ().
You cannot self-invoke a function declaration.
This is the self-invoking anonymous function. It is executed while it is defined. Which means this function is defined and invokes itself immediate after the definition.
And the explanation of the syntax is: The function within the first () parenthesis is the function which has no name and by the next (); parenthesis you can understand that it is called at the time it is defined. And you can pass any argument in this second () parenthesis which will be grabbed in the function which is in the first parenthesis. See this example:
(function(obj){
// Do something with this obj
})(object);
Here the 'object' you are passing will be accessible within the function by 'obj', as you are grabbing it in the function signature.
Start here:
var b = 'bee';
console.log(b); // global
Put it in a function and it is no longer global -- your primary goal.
function a() {
var b = 'bee';
console.log(b);
}
a();
console.log(b); // ReferenceError: b is not defined -- *as desired*
Call the function immediately -- oops:
function a() {
var b = 'bee';
console.log(b);
}(); // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
Use the parentheses to avoid a syntax error:
(function a() {
var b = 'bee';
console.log(b);
})(); // OK now
You can leave off the function name:
(function () { // no name required
var b = 'bee';
console.log(b);
})();
It doesn't need to be any more complicated than that.
Self-executing functions are typically used to encapsulate context and avoid name collusions. Any variable that you define inside the (function(){..})() are not global.
The code
var same_name = 1;
var myVar = (function() {
var same_name = 2;
console.log(same_name);
})();
console.log(same_name);
produces this output:
2
1
By using this syntax you avoid colliding with global variables declared elsewhere in your JavaScript code.
It is a function expression, it stands for Immediately Invoked Function Expression (IIFE). IIFE is simply a function that is executed right after it is created. So insted of the function having to wait until it is called to be executed, IIFE is executed immediately. Let's construct the IIFE by example. Suppose we have an add function which takes two integers as args and returns the sum
lets make the add function into an IIFE,
Step 1: Define the function
function add (a, b){
return a+b;
}
add(5,5);
Step2: Call the function by wrap the entire functtion declaration into parentheses
(function add (a, b){
return a+b;
})
//add(5,5);
Step 3: To invock the function immediatly just remove the 'add' text from the call.
(function add (a, b){
return a+b;
})(5,5);
The main reason to use an IFFE is to preserve a private scope within your function. Inside your javascript code you want to make sure that, you are not overriding any global variable. Sometimes you may accidentaly define a variable that overrides a global variable. Let's try by example. suppose we have an html file called iffe.html and codes inside body tag are-
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Well, above code will execute with out any question, now assume you decleard a variable named document accidentaly or intentional.
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
const document = "hi there";
console.log(document);
</script>
</body>
you will endup in a SyntaxError: redeclaration of non-configurable global property document.
But if your desire is to declear a variable name documet you can do it by using IFFE.
<body>
<div id = 'demo'></div>
<script>
(function(){
const document = "hi there";
this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
console.log(document);
})();
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Output:
Let's try by an another example, suppose we have an calculator object like bellow-
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
console.log(calculator.add(5,10));
</script>
</body>
Well it's working like a charm, what if we accidently re-assigne the value of calculator object.
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
console.log(calculator.add(5,10));
calculator = "scientific calculator";
console.log(calculator.mul(5,5));
</script>
</body>
yes you will endup with a TypeError: calculator.mul is not a function iffe.html
But with the help of IFFE we can create a private scope where we can create another variable name calculator and use it;
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
var cal = (function(){
var calculator = {
sub:function(a,b){
return a-b;
},
div:function(a,b){
return a/b;
}
}
console.log(this.calculator.mul(5,10));
console.log(calculator.sub(10,5));
return calculator;
})();
console.log(calculator.add(5,10));
console.log(cal.div(10,5));
</script>
</body>
Output:
TL;DR: Expressions can be enclosed in parenthesis, which would conflict with function calling if the expression and block forms of function were combined.
I like counter-examples because they paint a great picture of the logic, and noone else listed any. You might ask, "Why can't the browser see function(){}() and just assume its an expression?" Let's juxtapose the issue with three examples.
var x;
// Here, fibonacci is a block function
function fibonacci(x) {
var value = x < 2 ? x : fibonacci(x-1) + fibonacci(x-2);
if (x === 9) console.log("The " + x + "th fibonacci is: " + value);
return value;
}
(x = 9);
console.log("Value of x: " + x);
console.log("fibonacci is a(n) " + typeof fibonacci);
Observe how things change when we turn the function into an expression.
var x;
// Here, fibonacci is a function expression
(function fibonacci(x) {
var value = x < 2 ? x : fibonacci(x-1) + fibonacci(x-2);
if (x === 9) console.log("The " + x + "th fibonacci is: " + value);
return value;
})
(x = 9);
console.log("Value of x: " + x);
console.log("fibonacci is a(n) " + typeof fibonacci);
The same thing happens when you use the not-operator instead of parenthesis because both operators turn the statement into an expression:
var x;
// Here, fibonacci is a function expression
! function fibonacci(x) {
var value = x < 2 ? x : fibonacci(x-1) + fibonacci(x-2);
if (x === 9) console.log("The " + x + "th fibonacci is: " + value);
return value;
}
(x = 9);
console.log("Value of x: " + x);
console.log("fibonacci is a(n) " + typeof fibonacci);
By turning the function into an expression, it gets executed by the (x = 9) two lines down from it. Thanks to separate behaviors for expression functions and block functions, both examples run fine without ambiguity (specs-wise).
Name Scoping
Another important observation is that named block functions are visible to the entire scope, whereas function expressions are only visible to themselves. In other words, fibonacci is only visible to the last console.log when it is a block in the first example. In all three examples, fibonacci is visible to itself, allowing fibonacci to call itself, which is recursion.
Arrow Functions
Another aspect to the logic is arrow functions. The specs would have had to include arbitrary rules and exceptions for arrow functions if the definitions of block and expression functions were merged together:
function hello() {console.log("Hello World")}
(x) => console.log("hello " + x)
console.log("If you are reading this, no errors occurred");
Although function blocks work fine, function expressions followed by an arrow function produce a syntax error:
! function hello() {console.log("Hello World")}
(x) => console.log("hello " + x)
console.log("If you are reading this, no errors occurred");
Here, it is ambiguous whether the (x) on line two is calling the function on the preceding line or whether it is the function arguments for an arrow function.
Note that arrow functions have been indeed to the ECMAScript standard over the years and were not a factor in the initial design of the language; my point is that a differentiation between expression and block functions helps JavaScript syntax to be a little more logical and coherent.
Self-executing anonymous function. It's executed as soon as it is created.
One short and dummy example where this is useful is:
function prepareList(el){
var list = (function(){
var l = [];
for(var i = 0; i < 9; i++){
l.push(i);
}
return l;
})();
return function (el){
for(var i = 0, l = list.length; i < l; i++){
if(list[i] == el) return list[i];
}
return null;
};
}
var search = prepareList();
search(2);
search(3);
So instead of creating a list each time, you create it only once (less overhead).
It is called IIFE - Immediately Invoked Function Expression. Here is an example to show it's syntax and usage. It is used to scope the use of variables only till the function and not beyond.
(function () {
function Question(q,a,c) {
this.q = q;
this.a = a;
this.c = c;
}
Question.prototype.displayQuestion = function() {
console.log(this.q);
for (var i = 0; i < this.a.length; i++) {
console.log(i+": "+this.a[i]);
}
}
Question.prototype.checkAnswer = function(ans) {
if (ans===this.c) {
console.log("correct");
} else {
console.log("incorrect");
}
}
var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);
var questions = [q1, q2, q3];
var n = Math.floor(Math.random() * questions.length)
var answer = parseInt(prompt(questions[n].displayQuestion()));
questions[n].checkAnswer(answer);
})();
Already many good answers here but here are my 2 cents :p
You can use IIFE (Immediately Invoked Function Expression) for:
Avoiding pollution in the global namespace.
Variables defined in IIFE (or even any normal function) don't overwrite definitions in global scope.
Protecting code from being accessed by outer code.
Everything that you define within the IIFE can be only be accessed within the IIFE. It protects code from being modified by outer code. Only what you explicitly return as the result of function or set as value to outer variables is accessible by outer code.
Avoid naming functions that you don't need to use repeatedly.
Though it's possible to use a named function in IIFE pattern you don't do it as there is no need to call it repeatedly, generally.
For Universal Module Definitions which is used in many JS libraries. Check this question for details.
IIFE is generally used in following fashion :
(function(param){
//code here
})(args);
You can omit the parentheses () around anonymous function and use void operator before anonymous function.
void function(param){
//code here
}(args);
IIFE (Immediately invoked function expression) is a function which executes as soon as the script loads and goes away.
Consider the function below written in a file named iife.js
(function(){
console.log("Hello Stackoverflow!");
})();
This code above will execute as soon as you load iife.js and will print 'Hello Stackoverflow!' on the developer tools' console.
For a Detailed explanation see Immediately-Invoked Function Expression (IIFE)
One more use case is memoization where a cache object is not global:
var calculate = (function() {
var cache = {};
return function(a) {
if (cache[a]) {
return cache[a];
} else {
// Calculate heavy operation
cache[a] = heavyOperation(a);
return cache[a];
}
}
})();
The following code:
(function () {
})();
is called an immediately invoked function expression (IIFE).
It is called a function expression because the ( yourcode ) operator in Javascript force it into an expression. The difference between a function expression and a function declaration is the following:
// declaration:
function declaredFunction () {}
// expressions:
// storing function into variable
const expressedFunction = function () {}
// Using () operator, which transforms the function into an expression
(function () {})
An expression is simply a bunch of code which can be evaluated to a single value. In case of the expressions in the above example this value was a single function object.
After we have an expression which evaluates to a function object we then can immediately invoke the function object with the () operator. For example:
(function() {
const foo = 10; // all variables inside here are scoped to the function block
console.log(foo);
})();
console.log(foo); // referenceError foo is scoped to the IIFE
Why is this useful?
When we are dealing with a large code base and/or when we are importing various libraries the chance of naming conflicts increases. When we are writing certain parts of our code which is related (and thus is using the same variables) inside an IIFE all of the variables and function names are scoped to the function brackets of the IIFE. This reduces chances of naming conflicts and lets you name them more careless (e.g. you don't have to prefix them).
The reason self-evoking anonymous functions are used is they should never be called by other code since they "set up" the code which IS meant to be called (along with giving scope to functions and variables).
In other words, they are like programs that "make classes', at the beginning of program. After they are instantiated (automatically), the only functions that are available are the ones returned in by the anonymous function. However, all the other 'hidden' functions are still there, along with any state (variables set during scope creation).
Very cool.
In ES6 syntax (posting for myself, as I keep landing on this page looking for a quick example):
// simple
const simpleNumber = (() => {
return true ? 1 : 2
})()
// with param
const isPositiveNumber = ((number) => {
return number > 0 ? true : false
})(4)
This function is called self-invoking function. A self-invoking (also called self-executing) function is a nameless (anonymous) function that is invoked(Called) immediately after its definition. Read more here
What these functions do is that when the function is defined, The function is immediately called, which saves time and extra lines of code(as compared to calling it on a seperate line).
Here is an example:
(function() {
var x = 5 + 4;
console.log(x);
})();
An immediately invoked function expression (IIFE) is a function that's executed as soon as it's created. It has no connection with any events or asynchronous execution. You can define an IIFE as shown below:
(function() {
// all your code here
// ...
})();
The first pair of parentheses function(){...} converts the code inside the parentheses into an expression.The second pair of parentheses calls the function resulting from the expression.
An IIFE can also be described as a self-invoking anonymous function. Its most common usage is to limit the scope of a variable made via var or to encapsulate context to avoid name collisions.
This is a more in depth explanation of why you would use this:
"The primary reason to use an IIFE is to obtain data privacy. Because JavaScript's var scopes variables to their containing function, any variables declared within the IIFE cannot be accessed by the outside world."
http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html
Normally, JavaScript code has global scope in the application. When we declare global variable in it, there is a chance for using the same duplicate variable in some other area of the development for some other purpose. Because of this duplication there may happen some error. So we can avoid this global variables by using immediately invoking function expression , this expression is self-executing expression.When we make our code inside this IIFE expression global variable will be like local scope and local variable.
Two ways we can create IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
OR
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
In the code snippet above, “var app” is a local variable now.
Usually, we don't invoke a function immediately after we write it in the program.
In extremely simple terms, when you call a function right after its creation, it is called IIFE - a fancy name.
This question already has answers here:
Variables with the same name, but the local scope variable isn't being used, why?
(4 answers)
Closed 3 years ago.
So I thought I understood hoisting in JavaScript until I saw something like this:
function hoist(a) {
console.log(a);
var a = 10;
}
hoist(5);
The code above outputs 5, not undefined!
As per my understanding, the function looks like this to the interpreter:
function hoist(a) {
var a; // This should overshadow the parameter 'a' and 'undefined' should be assigned to it
console.log(a); // so this should print undefined
a = 10; // now a is assigned 10
}
So what's happening here?
You would be right if the var was called b, but the var a already exists. redeclaring a javascript variable that already exists doesn't do anything. It will not change the value to undefined. Try it.
function hoist(a) {
var a; // no op, does not change a to undefined.
console.log(a);
a = 10;
}
hoist(18);
This falls back in the section Only declarations are hoisted in the MDN (to link some documentation, at least).
The second example given there is the exact one you're looking for:
num = 6;
console.log(num); // returns 6
var num; // or, really, var num = whatever.
To just recall what is said:
If you declare the variable after it is used, but initialize it beforehand, it will return the value.
Hoisting a variable means that the variable name is known to the compiler from the beginning of the block. It does not re-introduce, overwrite, clear or reset the variable if it already exists.
Until something is assigned, the value of that variable is undefined, but hoisting itself does nothing to the value of the variable.
It so happens that a function parameter is also a way of declaring a variable, like an invisible var statement, followed by an assignment that happens as the function gets called, before any of the actual function body executes.
Hoisting is still working as we expect, as we can see that the following snippet also outputs 5:
function hoist(a) {
var a;
console.log(a);
a = 10;
}
hoist(5);
What we really have here is a function parameter, a, being redeclared inside the function where its value has already been initialized to 5.
you are correct that hoisting would work this way inside of that function.
In this particular example we pass an argument/parameter to our function and it changes how it will be interpreted. Just take a look:
function hoist(a) { // here's our 'a' parameter gets replaced by '5' that we passed while execution of this function
var a; // with no new value it does nothing
console.log(a); // so this will print 5 that we passed to this function
a = 10; // now a is assigned 10 and next console.log() would show a new value of 'a' variable
}
Hoisting has to do with calling a function before it is declared, as javascript will push the function declarations to the top. The parameter a and the variable a don't related to hoisting in this case.
I have the following code, where I declare a function and after it, a variable with the same name as the function:
function a(x) {
return x * 2;
}
var a;
alert(a);
I expected this to alert undefined, but if I run it, the alert will display the following:
function a(x) {
return x * 2
}
If I assign a value to the variable (like var a = 4), the alert will display that value (4), but without this change a will be recognized as a function.
Why is this happening?
Functions are a type of object which are a type of value.
Values can be stored in variables (and properties, and passed as arguments to functions, etc).
A function declaration:
Creates a named function
Creates a variable in the current scope with the same name as the function (unless such a variable already exists)
Assigns the function to that variable
Is hoisted
A var statement:
Creates a variable in the current scope with the specified name (unless such a variable already exists)
Is hoisted
Doesn't assign a value to that variable (unless combined with an assignment operator)
Both your declaration and var statement are hoisted. Only one of them assigns a value to the variable a.
In JavaScript both function declaration and variable declarations are hoisted to the top of the function, if defined in a function, or the top of the global context, if outside a function. And function declaration takes precedence over variable declarations (but not over variable assignment).
Function Declaration Overrides Variable Declaration When Hoisted
First you declare a variable:
var a; // value of a is undefined
Second, the value of a is a function because function declaration takes precedence over variable declarations (but not over variable assignment):
function a(x) {
return x * 2;
}
And that is what you get when you call alert(a);.
But, if instead of declaring a variable you make variable assignment: var a = 4; then the assigned value 4 will prevail.
If you use a function name as variable name, its value is replaced by function body. So var a becomes your function a and thus your alert displays function a.
Edit But if you assign value to a like var a = "xya";. Then it function will be replaced by variable. As per Order of precedence
Variable assignment takes precedence over function declaration
Function declarations take precedence over variable declarations
You should also remember that var a is hoisted, which makes it more like this
var a; // placed
function a(x) {
return x * 2;
};
var a; // removed
alert (a); // a is replaced by function body
Remember that var a is hoisted, so if you assign 4 to a:
var a; // placed
function a(x) {
return x * 2;
};
var a = 4; // removed
a = 4 // added
alert (a); // a is now 4
First hoisting takes place. Function declaration takes precedence over variable declaration during hoisting.
During execution of the code, if variable is assigned at any point, then it is replaced, otherwise it remains the same function.
(Note: First read the code from Line 4 to Line 8. Then again read from beginning to end.)
console.log(a); // f a(){...} - Executed just after hoisting
console.log(b); // f b(){...} - Executed just after hoisting
var a = 100; // here variable is assigned
function a(x) {...};
function b(x) {...};
var b; // only a declaration here
console.log(a); // 100
console.log(b); // f b(){...}
ES6 comes with a better solution by defining SyntaxError: Identifier (?) has already been declared when using let / const instead of var.
let
function foo () {}
let foo;
// => SyntaxError: Identifier 'foo' has already been declared
const
function foo () {}
const foo = 1;
// => SyntaxError: Identifier 'foo' has already been declared
Note that const foo; does not work. It will cause SyntaxError: Missing initializer in const declaration
My question is really more about scope in JavaScript, rather then closures.
Let's take the following code:
var f = function () {
var n = 0;
return function () {
return n++;
};
}();
console.log(f());
console.log(f());
The above code outputs:
0
1
As you can see from the above code, f (self-invoked) returns a function, creating a closure of n.
So, it works with an anonymous function; thus, I then tried it with a named function:
var f2 = function () {
return n++;
};
var f = function () {
var n = 0;
return f2;
}();
console.log(f2()); // <= [n is not defined]
The above code doesn't work, with the error n is not defined. I assume that this is a scoping issue; but I cannot figure why exactly;
Why is it that the scope is the same with an anonymous, inner function but does not work with a named, outer function?
Also, in the second example, am I creating a closure?
The closure is created in the first example because the code in the anonymous function uses a local variable that is declared outside of the anonymous function.
In the second example the scope of the n variable in the function f2 is already decided when the function is declared. Creating a local variable with the same name doesn't change the meaning of the function, and using the function inside another function doesn't change it's scope. Thus, the function doesn't use the local variable.
scoping in javascript is lexical http://en.wikipedia.org/wiki/Scope_%28programming%29#Static_scoping_.28also_known_as_lexical_scoping.29
There is no way for f2 to figure out where it should take variable n.
In first example anonymous function is inside function f, in second - outside (f2 instead of anonymous). So, f2 cannot access variable n, because it is in another scope and inaccessible (invisible). Try put f2 declaration inside f.
In your second example, you are not creating a closure, you are simply returning a global variable. f2 is not being closed over because it was declared in a more general (in this case, global) scope, and n is declared in a more specific scope. Closure is possible down the scope chain "funnel," not up, and is only effective when all related entities are defined in the same scope.
We could rewrite your second example to make it work with a named function:
var f = function() {
var n = 0;
var f2 = function() {
return n++;
};
return f2;
}();
console.log(f());
console.log(f());
This would output, 0 and 1 as your first example did.
As the other answers have stated, its not about the function being named or anonymous, its about scope of n and f2. Since you declared f2 outside of f in your example, it had no access to the variable n declared inside the scope of f.