I wrote earlier: juejin.cn/post/684490… Looking back now, I feel I could have gone further. Creating a variable in JS is a three-step process,
- statement
- Initialize the
- The assignment
The surface properties
- Variables declared by let const cannot be promoted. Variables declared by var are promoted
- Let const cannot be declared repeatedly. Var can
- Const variables cannot be changed. If an object is declared, the value inside the object can be changed
Specific point again
-
Var is created and initialized at the same time, and the initialized value is undefined
-
Let const is created first and initialized at the assignment step, so accessing this variable without initialization throws an error
-
Const cannot be modified because of JS engine when accessing the variable will go to visit this memory address first, then go to access memory space, and finally get the content in the memory space, if is the assignment operation, also only has opened up a new memory space, and then bind their relationship, and the old memory space by the GC recycles it, The memory address declared by const is bound to an immutable relationship with the memory space
-
The let in the body of the loop is because each time a new variable is created, it can be understood as forming a separate closure
Performance under Babel
We first have to install the environment, if the situation has been stuck, it is recommended to stand in the window to look out for 5 minutes, come back
npm install babel-loader -DCopy the code
npm install @babel/core @babel/preset-env @babel/plugin-transform-runtime -DCopy the code
npm install @babel/runtime @babel/runtime-corejs3Copy the code
Modify the configuration in WebPack
let path = require('path')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env"],
plugins: [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3
}
]
]
}
},
exclude: /node_modules/
}
]
}
}Copy the code
A simple example
{
let a = 1
}
console.log(a);Copy the code
Compiled code:
{
var _a = 1;
}
console.log(a);Copy the code
Let /const each {} is an independent scope. The outside can’t access the inside, but the inside can access the outside
Classic Interview questions
var funcArr = [];
for (let i = 0; i < 3; i++) {
funcArr[i] = function () {
console.log(i);
};
}
funcArr[0]();Copy the code
What it looks like after compilation:
var funcArr = [];
var _loop = function _loop(i) {
funcArr[i] = function () {
console.log(i);
};
};
for (var i = 0; i < 3; i++) {
_loop(i);
}
funcArr[0]();Copy the code
You can see that the original for loop has been split into two parts, which should make sense, but the only detail is
var _loop = function _loop(i) {}Copy the code
Function (_loop) is ignored, so setTimeout is used to pass a value.
SetTimeout version
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
});
}Copy the code
The compiled:
for (var i = 0; i < 3; i++) {
(function() { console.log(i); })}Copy the code
After compiling the code is generated a “malformed” immediately execute the function, because I save part of the irrelevant code ~ interested students can copy the code to try
What about let?
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
});
}Copy the code
The compiled:
var _loop = function _loop(i) {
(function() { console.log(i); })};for (var i = 0; i < 3; i++) {
_loop(i);
}Copy the code
If we manually add a parenthesized executor, the result will be the same as if we had used let, so IIFE is the best idea in the world