In this following snipet, I just want to understand why console.log(abc in this);
is print true , but in next line console.log(abc);
getting undefined
console.log(this.abc);//undefined
console.log(abc in this);//true
console.log(abc);//undefined
{
function abc(){
console.log("hello");
}
}
console.log(abc); //ƒ abc(){console.log("hello");
Could anyone of you explain how Hoisting and Block statement working in this case?
In sloppy mode, this
refers to the global object. A function inside a plain non-function block like that will have its variable name hoisted to the outer scope, but the actual function will not be assigned to the outer variable (to the window property) until the inner block is executed.
See here for details:
What are the precise semantics of block-level functions in ES6?
As explained in that other question, to the interpreter, your code looks something like this:
window.abc = undefined; // top-level hoisting assigns to window properties
console.log(window.abc); // undefined
console.log(window.abc in window); // true
console.log(window.abc); // undefined
{
var _abc = function abc() {
console.log("hello");
};
window.abc = _abc;
}
console.log(window.abc); //ƒ abc(){console.log("hello");
The reason abc in this
is true is because abc
has been initialized as a property of the window object, but it hasn't been assigned a value yet. It's similar to what's happening here:
const obj = { foo: undefined };
console.log('foo' in obj);
Simply put, with console.log(abc in this);
it check if it is there, which it is, hence logging true
, though you can't access it yet, hence getting undefined
for the other two console.log
executing before the function declaration.
If you want to know why that happen the answer is simple, hoisting moves all the declarations to the top of his scope, so:
console.log(this.abc); //undefined
console.log(abc in this); //true
console.log(abc); //undefined
function abc() {
console.log("hello");
}
console.log(abc); //ƒ abc(){console.log("hello");
so in the inner function, the function abc() is declared at the top of the current scope staying almost at the same position, but just the declaration, so the var abc is declared then assigned, when you try access at the bottom he already knows the function, in the first console.log where you get undefined
console.log(abc) the function _abc is not decalred yet, but in the second example you have access to it because it access the windows object and get the abc.
so in short terms, javascript first initialize variables, since at the second console.log all the variables are already declared and they are declared at the window object, accessing abc on this works fine.