ES6:在'严格模式'下for循环中的多个let赋值

时间:2018-02-07 05:06:44

标签: javascript ecmascript-6 let

我正在尝试'严格模式'并在for循环中使用关键字let,如下所示:

  (function() {

    "use strict";

    var numbers = [1,2,3,4,5];
    var value;


    for (let i = j = 0; i < numbers.length; i++) {
      j += numbers[i];
      value = j;
    }
      console.log ("\tThe reduced value is: ", value);    
  })();    

这会产生一个Uncaught ReferenceError:j未定义,但通过删除'use strict',代码运行正常。

代码是我jsfiddle

的缩小子集

3 个答案:

答案 0 :(得分:4)

问题如你所料,for循环中的初始化语句:

let i = j = 0;

此声明与:

相同
let i = (j=0);

与:

相同
j = 0; // would throw : Uncaught ReferenceError: j is not defined
let i = j;

如果要修复strict-mode错误,则需要使用let j = 0显式地将j声明为变量;

由于提升,它在草率模式下工作,这将在全局范围内创建变量j。 (https://www.w3schools.com/js/js_hoisting.asp

编辑:Bergi是对的,我混淆了概念,由于范围链而不是悬挂,它在全球范围内变得可用。如果变量在本地范围内未声明,则会查看变量的外部词法范围。如果它仍未在那里定义,它会继续向上移动范围链,直到达到全局范围。如果它仍未在那里定义,那么它会自动在全局范围内定义,这是您每次使用j时引用的变量。

答案 1 :(得分:2)

施工

let i = j = 0

实际上与关键字let无关。 然而

让我们来看看它在幕后的作用:

let i // declares i
j = 0 // assigns a variable j to 0 that is not declared
      // If it does not exist it creates the variable on the `window` object.
i = j // in fact i = window.j

要正确使用

let i = 0, j = 0

答案 2 :(得分:0)

在JavaScript中,如果两个或多个具有相同优先级的运算符出现在表达式中,则关联性规则将起作用。

更多信息:Operator Precedence And Associativity

=正确具有关联性。所以在试图评估时

let i = j = 0;,JavaScript实际上首先尝试执行:

j = 0; // Throws Uncaught ReferenceError: j is not defined in strict mode

但是通过在全局上下文中创建j,在草率模式中忽略了这一点。