简体   繁体   中英

ES6: Multiple let assignment inside for-loop in 'strict mode'

I am trying out 'strict mode' and using keyword let inside of a for-loop like this:

  (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);    
  })();    

This produces an Uncaught ReferenceError: j is not defined, but by removing 'use strict' the code runs fine.

The code is reduced subset of my jsfiddle

The problem is as you would expect, the initialiser statement in your for loop:

let i = j = 0;

This statement is identical to:

let i = (j=0);

which is the same as:

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

If you want to fix the strict-mode error, you need to explicitly declare j as a variable with let j = 0;

It works in sloppy mode due to hoisting, which will create a variable j in the global scope. ( https://www.w3schools.com/js/js_hoisting.asp )

Edit: Bergi is right, I mixed up the concepts, it becomes available in the global scope due to the the scope chain, not hoisting. If a variable is undeclared in the local scope, it looks at the outer lexical scope for the variable. If it's still not defined there, it keeps going up the scope chain until it hits the global scope. If it's still not defined there, then it automatically gets defined in the global scope and that is the variable you reference every time you use j.

The construction

let i = j = 0

has actually nothing to do with the keyword let . Yet

Let's look at what it does under the hood:

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

To make it right use

let i = 0, j = 0

In JavaScript, if two or more operators with the same level of precedence appear in an expression then Associativity rules comes into play.

For more: Operator Precedence And Associativity

= has the Associativity from Right to Left . So when Trying to evaluate

let i = j = 0; , JavaScript actually first tries to execute:

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

But ignores that in sloppy mode by creating j in the global context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM