Javascript 无法理解技巧变量 "hoisting":为什么它是 NaN 值?

Javascript Couldn't understand a trick variable "hoisting": why it's NaN value?

我尝试JavaScript了解它的提升策略,但更加困惑:

function f(i){this.i+=i}
i=2
f(3)
console.log(i)

输出

5

(1) 这是我所期望的。然后我尝试重新定位 "i=2" 语句:

function f(i){this.i+=i}
f(3)
console.log(i)
i=2

输出

NaN

(2) 为什么会这样?我预计因为 "i" 被提升到整个程序的前面,为什么它打印 "NaN"?一种可能的答案是,程序被编译器重构为:

var i
function f(i){this.i+=i}
f(3)
console.log(i)
i=2

(3) 所以当 "console.log(i)" 时,我没有被赋值,所以它是 "NaN"--->但是我尝试了下面的程序:

function f(i){this.i+=i}
f(3)
i=2
console.log(i)

如果上面的解释是正确的,我希望这也应该输出"NaN"。但实际上,它输出

2

这就更奇怪了。 "hoisting" 在这种情况下是否有效?

(4) 更有趣的是,如果我将程序更改为:

var i
function f(i){this.i+=i}
f(3)
console.log(i)
i=2

然后输出

undefined

这是为什么?

(5) 对于程序:

var i
function f(i){this.i+=i}
f(3)
i=2
console.log(i)

它再次输出

2

你能解释一下上面的观察结果吗,因为它确实来自我对 "hoisting" 是什么的理解?

仅仅因为定义了 i,并不意味着它具有数据类型。在 JavaScript 中只有几种设置数据类型,Number 是其中之一。

如果没有事先赋值,函数就无法知道您使用的是来自 "overloaded" 加操作数的数字还是字符串。

通过提升,它不排除指令流,只是变量声明发生的地方。如果一个变量没有初始化,它在第一次赋值之前一直是一个无类型变量。

作为,这与提升无关,与contextscope有关,特别是在非严格模式环境中。

function f(i){this.i+=i}
i=2
f(3)
console.log(i)

i=2 等同于 window.i=2。由于这是在非严格模式下,thiswindow,因此 this.i+=i 等同于 window.i+=i,其中右侧的 i 由函数参数。所以这应该可以解释 5.

的输出

function f(i){this.i+=i}
f(3)
console.log(i)
i=2

这里唯一的区别是i=2this.i+=i之后执行。将数字添加到未声明的变量会产生预期的 NaN

var i
function f(i){this.i+=i}
f(3)
console.log(i)
i=2

此处,var i 附加到 window 作用域,因为这是非严格模式,因此 this.i+=i 将数字添加到已声明但未初始化的值,window.i,结果仍然是 NaN.

var i
function f(i){this.i+=i}
f(3)
i=2
console.log(i)

在这里,希望是很明显的。 i=2 将覆盖之前发生的任何事情(在本例中为 isNaN(i)===true.

有什么问题吗? Class 被驳回。

要记住的一件非常重要的事情是 Javascript 只会提升函数声明,而不是调用函数时。

function f(i) { ... } //will be hoisted
f(2); //won't be hoisted

继续...

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

这输出 NaN 因为当 undefined 的变量被视为 Number 时,它变成 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

这会输出 2,因为 i 在记录 i 之前被分配了 2 的值。

...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

这会输出 undefined,因为 i 在记录之前从未分配过值。

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

这会输出 2,因为 i 在记录 i 之前被分配了 2 的值。