代码之家  ›  专栏  ›  技术社区  ›  Hind Forsum

Javascript无法理解技巧变量“living”:为什么它是NaN值?

  •  1
  • Hind Forsum  · 技术社区  · 8 年前

    我试着用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)”时,没有为i赋值,所以它是“NaN”--->但我尝试了以下程序:

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

    如果上面的解释是正确的,我希望它也会输出“NaN”。但事实上,它输出

    2
    

    这更奇怪。在这种情况下,“吊装”起作用了吗?

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

    变量i
    函数f(i){this.i+=i}
    f(3)
    控制台.log(i)
    i=2
    

    然后输出

    undefined
    

    这是为什么?

    (5) 对于该计划:

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

    同样,输出

    2.
    

    你能解释一下上面的观察结果吗?因为这真的是我对什么是“吊装”的理解?

    3 回复  |  直到 7 年前
        1
  •  4
  •   Community Zohar Peled    7 年前

    @zzzzBov has pointed out ,这与吊装无关,与一切有关 上下文 范围 ,特别是在非严格模式环境中。

    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 附加到 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 .

    有什么问题吗?下课。

        2
  •  2
  •   TrampolineTales    8 年前

    需要记住的一件非常重要的事情是,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 被赋值为 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
    console.log(i) //i is logged, which is currently undefined
    i=2 //i has the value of 2 assigned to it
    

    此输出 未定义 因为 在它被记录之前,从未给它赋值。

    同样,输出 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. 因为 被赋值为 2. 就在之前 已记录。

        3
  •  0
  •   Paurian    8 年前

    如果事先没有赋值,函数就无法知道您是在使用“重载”加法操作数中的数字还是字符串。

    有了提升,就在变量声明发生的地方,它并不排除指令流。如果变量不是 已初始化