我正在尝试'严格模式'并在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
的缩小子集答案 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
,在草率模式中忽略了这一点。