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" 加操作数的数字还是字符串。
通过提升,它不排除指令流,只是变量声明发生的地方。如果一个变量没有初始化,它在第一次赋值之前一直是一个无类型变量。
作为,这与提升无关,与context和scope有关,特别是在非严格模式环境中。
function f(i){this.i+=i}
i=2
f(3)
console.log(i)
i=2
等同于 window.i=2
。由于这是在非严格模式下,this
是 window
,因此 this.i+=i
等同于 window.i+=i
,其中右侧的 i
由函数参数。所以这应该可以解释 5
.
的输出
function f(i){this.i+=i}
f(3)
console.log(i)
i=2
这里唯一的区别是i=2
在this.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
的值。
我尝试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" 加操作数的数字还是字符串。
通过提升,它不排除指令流,只是变量声明发生的地方。如果一个变量没有初始化,它在第一次赋值之前一直是一个无类型变量。
作为
function f(i){this.i+=i}
i=2
f(3)
console.log(i)
i=2
等同于 window.i=2
。由于这是在非严格模式下,this
是 window
,因此 this.i+=i
等同于 window.i+=i
,其中右侧的 i
由函数参数。所以这应该可以解释 5
.
function f(i){this.i+=i}
f(3)
console.log(i)
i=2
这里唯一的区别是i=2
在this.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
的值。