I tried JavaScript to understand its hoisting strategy, but got more confused:
function f(i){this.i+=i}
i=2
f(3)
console.log(i)
It outputs
5
(1) This is what my expected. Then I tried to relocalte "i=2" statement:
function f(i){this.i+=i}
f(3)
console.log(i)
i=2
It outputs
NaN
(2) Why is that? I expected because "i" is hoisted to the front of the whole program, why it prints "NaN"? One possible answer is, the program is refactored by compiler to be:
var i
function f(i){this.i+=i}
f(3)
console.log(i)
i=2
(3) So when "console.log(i)", i has not be assigned any value, so it's "NaN"--->But I tried the program below:
function f(i){this.i+=i}
f(3)
i=2
console.log(i)
If the above explanation was correct, I expect this should also output "NaN". But in fact, it outputs
2
This is even more weird. Did "hoisting" worked at all in this case?
(4) More interestingly, if I change the program to be:
var i
function f(i){this.i+=i}
f(3)
console.log(i)
i=2
Then it outputs
undefined
Why is that?
(5) And for the program:
var i
function f(i){this.i+=i}
f(3)
i=2
console.log(i)
It again, outputs
2
Could you explain the above observations, as it really comes out of my understanding of what "hoisting" is?
One very important thing to remember is that Javascript will only hoist function declarations, not when you call a function.
function f(i) { ... } //will be hoisted
f(2); //won't be hoisted
Moving on...
I tried to relocalte "i=2" statement...It outputs
NaN
...Why is that? I expected because "i" is hoisted to the front of the whole program, why it prints "NaN"?
function f(i){this.i+=i}
f(3) //the function executes i = undefined+3, which is NaN
console.log(i) //i is logged, which is currently NaN
i=2 //i has the value of 2 assigned to it
This outputs NaN
because when a variable which is undefined
is treated like a Number
, it becomes NaN
.
I expect this should also output "NaN". But in fact, it outputs
2
This is even more weird. Did "hoisting" worked at all in this case?
function f(i){this.i+=i}
f(3) //the function executes i = undefined+3, which is NaN
i=2 //i has the value of 2 assigned to it
console.log(i) //i is logged, which is currently 2
This outputs 2
because i
is assigned the value of 2
just before i
is logged.
...it outputs
undefined
Why is that?
var i //i is undefined
function f(i){this.i+=i} //f is hoisted and is line 1
f(3) //the function assigns (undefined + 3) to a variable which is never referenced
console.log(i) //i is logged, which is currently undefined
i=2 //i has the value of 2 assigned to it
This outputs undefined
because i
never had a value assigned to it before it was logged.
It again, outputs
2
var i //i is undefined
function f(i){this.i+=i} //f is hoisted and is line 1
f(3) //the function assigns (undefined + 3) to a variable which is never referenced
i=2 //i has the value of 2 assigned to it
console.log(i) //i is logged, which is currently 2
This outputs 2
because i
is assigned the value of 2
just before i
is logged.