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
- Performance is too slow
- 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