ES6 uses let and const, which in effect introduces block-level scopes. Prior to ES5, there were only global and function scopes

Consider the output value of the following example code

for (var i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i);
  }, 100);
}
Copy the code

There are 10 10s printed here, and since there is only one global variable I, we can solve this problem by executing the function immediately

for (var i = 0; i < 10; i++) {
  (function(i) {
    setTimeout(function () {
      console.log(i);
    }, 100);
  })(i);
}
Copy the code

If you could simply use the let command in an ES6 environment, it would create a scope for each loop. The reason why it remembers the last value is because the JS engine remembers the last value of the loop.

for (let i = 0; i < 10; i++) {
  setTimeout((a)= > {
    console.log(i);
  }, 100);
}
Copy the code

The above example is just a quick review of one of the pains of not having block-level scopes. In fact, we may have used Babel early on when we wrote our projects. This is what we need to talk about later, and how it converts lets and const to es5-enabled environments.

So with all that foreshadowing, let’s talk about this particular scope. Here’s an example

try {
  throw 5;
}catch(e) {
  console.log(e);
}
console.log(e); //error e is not defined
Copy the code

Try creates a block-level scope. In the global context, a does not exist, so an error is reported. If you’re smart enough, you might think that you can create block-level scopes with a try, which is theoretically possible, but there are actually two problems

  1. Performance is too slow
  2. Syntax ugly, error to display

What does Babel do with the example above

"use strict";

var _loop = function _loop(i) {
  setTimeout(function() {
    console.log(i);
  }, 100);
};

for (var i = 0; i < 10; i++) {
  _loop(i);
}
Copy the code

As you can see, this is basically the same as the immediate function, but using the immediate function to create block-level scopes requires a little attention to the reference of this to such examples as this

const obj = {
  foo() {
    for (let i = 0; i < 5; i += 1) {
      setTimeout((a)= > {
        console.log(this.arr[i]);
      }, 1000); }},arr: [1.2.3.4.5]};Copy the code

The arrow function does not have its own this object, which is a defining object rather than a runtime object, in this case pointing to obj; If we want to convert the above code to code supported by the ES5 environment, we can do so through scoped rules

(function() {
  var _this = this;
  setTimeout(function() {
    console.log(_this.arr[i]);
  }, 1000); }) ();Copy the code

That’s all you need