Summary: let and const
One: let and const have in common
1. Only takes effect at block level scope
let:
for(let i=0; i<1; i++) { console.log(i)//0 } console.log(i) // error
const:
if(true) { const max = 5; } console.log(max)//Uncaught ReferenceError: max is not defined
2. There is no variable promotion
let:
console.log(foo); // output ReferenceError
let foo="123";
const:
console.log(foo); // 输出 foo is not defined var foo = 2;
3. Repeated declaration of variables is not allowed
let:
// Error reporting function func() { let a = 10; var a = 1; } // Error reporting function func() { let a = 10; let a = 1; } Therefore, parameters cannot be redeclared inside a function. function func(arg) { let arg; // Error report } function func(arg) { { let arg; // no error } }
const:
var message = "Hello!"; let age = 25; // The following two lines will report an error const message = "Goodbye!" ; const age = 30;
4. Temporary dead zone (as long as there are let or const commands in the block-level scope, the variables they command are bound in this area and are no longer affected by external influences)
let:
var tmp = 123 ; if (true) { tmp = 'abc'; // ReferenceError let tmp = “456”; }
const:
var tmp = 123 ; if (true) { tmp = 'abc'; // ReferenceError const tmp="456"; }
ES6 clearly stipulates that if there are let
and const
commands in a block, the variables declared by this block for these commands form an enclosing scope from the beginning. Anytime these variables are used before they are declared, an error will be reported.
Two: let
1. Special case: In the loop traversal, the loop variable is a parent scope, and the inside of the loop body is a separate child scope. Both are not affected.
for(let i=0; i<10;i++) { let i="abc"; console.log(i) } //abc //abc //abc
2. The difference between var and let
where
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 for(var i=0;i<10;i++){ setTimeout(function(){ console.log(i) //10(10) },1000) }
In the above code, i is declared by var, which does not belong to the body of the for loop, but belongs to global. When the for loop ends, i is already equal to 10, and then execute the method in the function.
let
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
Three: const
1.const declares a read-only constant. Once declared, the value of the constant cannot be changed.
const PI = 3.1415 ; console.log(PI) // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
2. What const actually guarantees is not that the value of the variable cannot be changed, but that the memory address pointed to by the variable cannot be changed. For simple types of data (numbers, strings, Boolean values), the value is stored in the one pointed to by the variable. memory address, and therefore equivalent to a constant.
But for data of composite types (mainly objects and arrays), the memory address pointed to by the variable is only a pointer, which const
can only be guaranteed to be fixed. As for whether the data structure it points to is variable, it cannot be at all. Controlled. Therefore, declaring an object as a constant must be done with great care.
const foo = {}; // Add a property to foo, which can be successful foo.prop = 123 ; foo.prop // 123 // Pointing foo to another object will give an error foo = {}; // TypeError: "foo" is read-only
In the above code, the constant foo
stores an address, which points to an object. The only thing that is immutable is this address, that is, it cannot be foo
pointed to another address, but the object itself is mutable, so new properties can still be added to it .
If you really want to freeze the object, you should use the Object.freeze
method.
const foo = Object.freeze({}); // In normal mode, the following line does not work; // In strict mode, this line will report an error foo.prop = 123;
In addition to freezing the object itself, the properties of the object should also be frozen. Below is a function that completely freezes an object.
var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, i) => { if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); } }); };