What is the difference between below snippets?
var a = 0;
function b(){
a = 10;
return function a(){};
}
b();
console.log(a); // => 10
return function a(){};
Here function ...
is an expression. A named function expression to be precise. The a
here doesn't matter much, it just gives the anonymous function a .name, but it's still just a function expression that you're returning.
return
function a(){};
This here is equivalent to:
return;
function a(){};
Here function a
is a declaration, not an expression. It is hoisted, creating a local name a
in the scope, shadowing the outer a
. I.e. it is equivalent to:
function b(){
var a = function () {};
a = 10;
return;
}
return
function a() {}
is same as
return;
function a() {}
after automatic semicolon insertion.
In second case, function a
is moved to the top of its scope. The code is same as
var a = 0;
function b() {
function a() {};
a = 10;
return;
}
b();
console.log(a);
As a
inside b()
is inner function and then overriden, it is not accessible from outside of b()
.
Here is the demo to understand how the hoisting works.
var a = 0;
function b() {
console.log(a); // function
a = 10;
console.log(a); // 10
return
function a() {};
}
console.log(b()); // undefined
console.log(a);
Let's assume.
You are playing cricket. bowler is on the way and you just hit your bat on the air.
Would it be shot? No!
So if we assume Hoisting
is cricket
, therefore there is no sense to hit ball till bowler does not throw the ball
Quick Example:
Hoisted
console.log('batsman hit but ', ballStatus()); // batsman hit but true
function ballStatus() {
return true;
}
Non-Hoisted
console.log('batsman hit but ', ballStatus()); // Uncaught TypeError: ballStatus is not a function
var ballStatus = function() {
return true;
}
Line-break may be used instead of semicolon.
This:
var a = 0;
function b(){
a = 10;
return // line-break
function a(){};
}
b();
console.log(a); // => 0
means this:
var a = 0;
function b(){
a = 10;
return; // <-- 'adds this semicolon'
function a(){};
}
b();
console.log(a); // => 0
If you need this line-break, you can do like this:
var a = 0;
function b(){
a = 10;
return (
function a(){}
)
}
b();
console.log(a);