A Javascript quiz about hoisting - javascript

var d = 1;
(function(){
d = '2'
console.log(typeof d)
function d() {
}
})()
console.log(typeof d)
Could you explain why the second log prints out "number"?
var d = 1;
(function(){
d = '2'
console.log(typeof d)
})()
console.log(typeof d)
I tried to remove the function from the IIFE, and the result of second log becomes "string". I am very confused about it.

The first code:
var d = 1;
(function(){
d = '2'
function d() {
}
})()
because of function hoisting (function definitions are hoisted to the top of the containing scope - I think I worded that right), it's identical to
var d = 1;
(function(){
function d() {
}
d = '2'
})()
Now, d inside the IIFE is declared locally, so the "global" d is irrelevant and untouched by d='2'

Related

Why can't I declare functions or variables at the block statement? [duplicate]

console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
====================
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a) // this code throws Uncaught SyntaxError: Identifier 'a' has already been declared
both above code snippets are same except the if block.why does the latter throws error when its permissible in javascript to delcare same variable twice in the same scope with var as below
function a(){};
var a = 10; //no error
Also for a slightly different scenario after removing var from `var a = 10 in the above code ,then it works fine but output is surprising
var a = 1;
if(true) {
function a(){};
a = 10;
}
console.log(a) //output:ƒ a(){}
I am surprised to see this output as I am expecting 10 ..because two variables declared inside the if block refer to the same variable declared above as javascript var doesnt respect block scope but functional scope...so why not the output for above should be 10?
where as the below code outputs 10 as i expected when replaced the function definition with function expression.
var a = 1;
if(true) {
var a = function(){ console.log() }
a = 10;
}
console.log(a) //output:10
This is surprising as javascript var doesn't respect block scope but functional scope...
Sure, but you didn't use var for the declaration of a in the block scope. You used a function declaration, which does respect block scopes (otherwise it would be completely invalid code, as in ES5 strict mode).
It's permissible in javascript to declare same variable twice in the same scope with var as below
Same applies here. The function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow redeclarations.
Case 1
console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
Will be rendered as
var a;
a = function(){}; // now a holds the value as a function
console.log(a); // output : f a(){}
a = 1; // a is a var that holds value 1
a = 10; // a is a var that holds value 10
console.log(a); // output : 10
Case 2
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true) {
a = function() {};
let a; // The function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow re-declarations.
var a; // throws Uncaught SyntaxError: Identifier 'a' has already been declared
a = 10;
}
console.log(a);
Case 3
var a = 1;
if(true){
function a(){};
a = 10;
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true) {
a = function() {};
let a;
a = 10;
}
console.log(a); // output : f a(){}
Case 4
var a = 1;
if(true){
var a= function(){console.log()}
a = 10;
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true) {
a = function(){console.log()}
a = 10;
}
console.log(a) // output:10
Case 5
var a = 1;
if(true){
function a(){};
a = 10;
console.log(a)
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true){
a = function() {};
let a;
a = 10;
console.log(a); // output:10
}
console.log(a); // output : f a(){}
The simple solution to this is to use IIFE
(function() {
var sahil = {
checkThis: function() {
console.log(this);
function checkOther() {
console.log(this);
}
checkOther(); // checkThis() function called in "global context", will
// return "this" as "window"
}
};
var moo = sahil.checkThis;
moo(); // moo() function called in "global context", will return "this" as "window" })();

Why multiple functions inside an IIFE execute the last function?

I have actually no idea how the output of this code is a number. Someone kindly help understanding with what logic is JS running in this example?
<script>
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)();
console.log(typeof f);
</script>
You're using the comma operator. You're basically executing g here
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)()
is similar to:
var temp = function g(){ return 2; }
f = temp() // returns 2
Because of the comma operator.
x = a, b;
This evaluates a, then it evaluates b, and the result of b is used. That is, a is only evaluated for its side effects, otherwise its result is discarded.
That means that
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)();
is a fancy way of writing
var f = (function g(){ return 2; })();
which is a fancy way of writing
var f = 2;
and 2 is a number.
Here f is not a function.
Instead contains the value returned by g function.
f currently holds to the value returned in IIFE
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)();
console.log(f);
</script>
So, right, the comma operator. But more important is the change of the context of the functions. They are not anymore accessable from the global scope.
Some expanations may be in this answer of Does the comma operator influence the execution context in Javascript?:
var f = (
function f() { return "1"; },
function g() { return 2; }
)();
console.log(f);
console.log(typeof f);
console.log(g()); // throws error: 'g' is not defined

JavaScript Closure - trying to understand following code

Coming from Java background trying to make sense out of the following code.
From:
https://medium.freecodecamp.com/lets-learn-javascript-closures-66feb44f6a44#.cbk6c4e9g
For function bar(c), which line passes argument c into bar(c) as I don't see it here.
Thanks.
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5); // Closure
/*
The function below executes the function bar which was returned
when we executed the function foo in the line above. The function bar
invokes boop, at which point bar gets suspended and boop gets push
onto the top of the call stack (see the screenshot below)
*/
moar(15);
When your first statement of function call var moar = foo(5) is executed
moar variable will be function bar(c){var d=30;return boop(x+a+b+c+d);
check the snippet for understanding
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
return bar;
}
var moor=foo(10);
console.log(moor);
2.After this statement moar(15),your are actually passing 15 to the bar method
It will execute bar method with c as 15. Now this function would return boop(80) which would just be -80
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5)
console.log(moar(15));
Hope it helps
moar(15) passes 15 into bar which gets copied into parameter c.
The // Closure comment is misleading because it is more useful to think of the closure being configured at the point of declaration of a function.
The reality is that the pointer to the outer lexical environment is configured when a function object is instantiated, and then this pointer is then copied to the execution context associated with any invocations of said function object.

"this" in function invocation javascript

// Situation 1
var a = function A() {
this.x = 1;
var b = function B () {
this.x = 2;
console.log('Method B : x = ' + this.x);
};
console.log('Method A : x = ' + this.x);
b();
}
When I call a() , my result is
Method A : x = 1
Method B : x = 2
But if I delete "this.x = 2" as :
// Situation 2
var a = function A() {
this.x = 1;
var b = function B () {
console.log('Method B : x = ' + this.x);
};
console.log('Method A : x = ' + this.x);
b();
}
My result will be
Method A : x = 1
Method B : x = 1
I don't understand why
In situation 2 : "this" of function B is referenced to "this" of function A
But
In situation 1 : "this.x" of function A isn't changed when assign "this.x = 2" in function B
My code runs on Chrome v23
Since, this.x = 2 is in the definition of function B, it doesn't take place until B is called, not when it's defined. Try this version and see:
// Situation 3
var a = function A() {
this.x = 1;
var b = function B () {
this.x = 2;
console.log('Method B : x = ' + this.x);
};
console.log('Method A before B: x = ' + this.x);
b();
console.log('Method A after B: x = ' + this.x);
}
The reason this.x is being changed in both a and b is because they're both referencing the window object.
I think you're having a misconception with this one; this.x is being changed after the call to b. We can see this if we reverse the calls:
b(); // 2
console.log('Method A : x = ' + this.x); // 2
Calling b() like you do, will result in this referencing the global object (window within a browser environment).
That explains your behavior, your're writting basically window.x = 1;
You didn't call b() until after the value of A was printed. Therefore the value of x was 1 and THEN it was changed to 2 by b.
If you call b() before printing a() the output will be
Method A : x = 2
Method B : x = 2
As b() will first change value then a() will log
This is the function
var a = function A() {
this.x = 1;
var b = function B () {
this.x = 2;
console.log('Method B : x = ' + this.x);
};
b();
console.log('Method A : x = ' + this.x);
}
​Both a and b reference the window object window.x.
this is a special keyword in javascript and it depends on the context. In your case function B() is in the context of function A(). So if you don't overwrite this.x in function B() it'll be the value you assigned in function A().

JavaScript global scope

I ran this code in my console but got undefined. However I expected it to return 1 because function 2 returns a, which is a var in the global scope.
Can you please explain where I'm mistaken? thank you.
var a = 1;
function f1() {var a = 1; f2();}
function f2() {return a;}
f1();
You aren't doing anything with the return value of f2. You'd need to do this:
var a = 1;
function f1() {var a = 1; return f2();} // NB pass the return value on
function f2() {return a;}
f1();

Categories