Javascript 无法理解一个技巧变量“提升”:为什么它是 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
这就更诡异了。在这种情况下,"吊装"是否有效?
(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
您能否解释一下上述观察结果,因为它确实来自我对"吊装"的理解?
正如@zzzzBov所指出的,这与提升无关,而与上下文和范围有关,特别是在非严格模式环境中。
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
.
有问题吗?下课了。
要记住的一件非常重要的事情是,Javascript 只会提升函数声明,而不是在调用函数时。
function f(i) { ... } //will be hoisted
f(2); //won't be hoisted
继续前进...
我试图重新定位"i=2"语句...它输出
NaN
...为什么?我预料到,因为"i"被吊到整个程序的前面,为什么它打印"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
。
我希望这也应该输出"NaN"。但实际上,它输出
2
这就更诡异了。在这种情况下,"吊装"是否有效?
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
的值。
。它输出
undefined
这是为什么?
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
因为在记录之前从未为其分配过值。
它再次输出
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
的值。
仅仅因为定义了 i,并不意味着它具有数据类型。在 JavaScript 中,只有几种集合数据类型,Number 就是其中之一。
如果没有事先赋值,函数就无法知道您使用的是"重载"加操作数中的数字还是字符串。
通过提升,它不排除指令的流动,只是在发生变量声明的地方。如果变量未初始化,则在第一次赋值之前,它将保持为非类型化变量。
- Scala提升了如何运行javascript函数并将返回值存储在变量中
- Javascript变量和函数提升
- 同一变量的多个声明的JavaScript提升
- JavaScript 没有函数的变量提升
- 提升变量和函数参数
- 在 JavaScript 中提升变量
- 为什么我的 JavaScript 提升的局部变量返回未定义,但提升的全局变量返回空白
- 在 Javascript 中提升函数和变量时遇到问题,任何人都可以帮助我
- JavaScript 提升函数与函数变量
- 提升局部变量掩蔽全局变量
- 全局变量的javascript提升
- angularjs中未按预期提升的变量
- 函数内部变量的Javascript提升
- Javascript-变量提升
- 闭合中变量的提升
- JavaScript从未执行的分支提升变量
- 在nodejs/async中提升JavaScript变量
- 不正确地使用Javascript变量提升
- 提升未声明'var'的JS变量
- 为什么if语句不计算函数中的提升变量