This series is the usual reading, learning, real-world projects have new features on es6 in, with a brief summary of the hair, the purpose is to record for later review; this series is expected to contain let / const, arrows function, deconstruction, new common method, Symbol, Set & Map, Proxy, reflect, Class, Module, Iterator, Promise, Generator, async / await
let / const brought us what?
let
- Bound variable lift
(function foo() { console.log(a); let a = 1; })(); // Uncaught ReferenceError: a is not defined
To conclude that one: Before variables, we must first declare the variable declaration always before use.
- It brought the block-level scope
// es5 (function(){ if(false) { var temp = 1; } console.log(temp); // undefined })(); // es6 (function(){ if(false) { let temp = 1; } console.log(temp); // Uncaught ReferenceError: temp is not defined })();
From the code, we can clearly see let's es6 of block-level scope, the block-level scope What application do? for example:
var fnArr = []; for(var i = 0; i < 5; i++) { fnArr.push(function() { console.log(i); }); } fnArr[0](); // 5 fnArr[1](); // 5 fnArr[2](); // 5 fnArr[3](); // 5 fnArr[4](); // 5 console.log(i); // 5
Without careful analysis, the results of the implementation is not surprising that some of it? Yes, we intended for internal use in variable loop i was leaked became a global variable, and each cycle of the for loop, the variable i has not been restated, virtually every function stored in an array referenced fnArr They are the same variable i, so that led to the current results, how to make the code run in accordance with our initial ideas? Es5 commonly used term solution
var fnArr1 = []; for(var i = 0; i < 5; i++) { (function(j) { fnArr1.push(function() { console.log(j); }); })(i) } fnArr1[0](); // 0 fnArr1[1](); // 1 fnArr1[2](); // 2 fnArr1[3](); // 3 fnArr1[4](); // 4 console.log(i); // 5
Appears to be solved, here actually used the method closure, fnArr1 function references in each of j is a copy of the current time cycle i, thus solves the previous problem, but there is a problem: Variable i still get leaked to the implicit global
var fnArr1 = []; for(let i = 0; i < 5; i++) { fnArr1.push(function() { console.log(i); }); } fnArr1[0](); // 0 fnArr1[1](); // 1 fnArr1[2](); // 2 fnArr1[3](); // 3 fnArr1[4](); // 4 console.log(i); // Uncaught ReferenceError: i is not defined
OK, problem solved, will only be replaced with let 'var', which is let the convenience.
- Prohibition of temporary dead zone & repeat statement
// What is prohibited declared repeatedly it? To not give a written explanation, a look often wording ES5 ( function () { var TEMP =. 1 ; var TEMP = 2 ; var TEMP = function () { return . 1 ; }; }) ();
The above code execution without any problems, final temp is assigned a function
(function() { let temp = 1; var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declared var temp = function() { return 1; }; })();
In the third row will throw an error: temp has been declared, yes, let the variables declared, the declaration is not allowed again, to give a few examples of consolidating:
(function() { var temp = 2; var temp = function() { return 1; }; let temp = 1; // Uncaught SyntaxError: Identifier 'temp' has already been declared })(); (function() { if(true) { let temp = 1; var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declared } })(); (function() { if(true) { let temp = 1; function temp() { // Uncaught SyntaxError: Identifier 'temp' has already been declared return 1; } } })();
See out of it? As long as the scope let declaration occurs, it is not permitted to declare variables with the same name again (including the function declaration)
var foo = 1; if(true) { foo = 2; // Uncaught ReferenceError: foo is not defined let foo; }
Let's see 'high-handed', right? As long as the scope let where the variable of the same name will be occupied let, not allowed to repeat the statement, but also let's follow the rules
- Global variables are no longer as properties of the window object
var foo = 1; (function() { bar = 2; })(); window.foo; // 1 window.bar; // 2
Yes, es5, the global variables (including the accidental leakage) will automatically be added as properties of the window object
let foo = 1; window.foo; // undefined
it is more than words. . .
const
- let owned properties, const has, at the same time there is a const: const declared variables must be initialized, and can not be reassigned
const temp = 1; temp = 2; // Uncaught TypeError: Assignment to constant variable.
Note that can not be reassigned, this is more accurate, in fact, declared const variables can be modified when the variable is initialized to declare const complex data types, variables declared const is variable, as to why he understand myself (variable identifier stored in complex data types only memory address it ...)
TEMP = const {}; temp.foo = 'AA'; // this is no problem TEMP = {foo: 'AA'}; // this will throw an exception
Variable declaration for the cycle
When recording let the front block-level scope, we used an example of a for loop, here we might as well try to resolve what for loop execution
var fnArr = []; for(var i = 0; i < 3; i++) { fnArr.push(function() { console.log(i); }); } // 伪代码 var fnArr; fnArr = []; { var i; i = 0; if(i < 3) { fnArr.push(function() { console.log(i); }) } i++; if(i < 3) { fnArr.push(function() { console.log(i); }); } i++; ... }
Unfortunately, there was clear all i see is a i. . . After that let it use?
var fnArr = []; for(let i = 0; i < 3; i++) { fnArr.push(function() { console.log(i); }); } // 伪代码 var fnArr; fnArr = []; { let i; i = 0; if(i < 3) { let i = i; fnArr.push(function() { console.log(i); }) } i++; if(i < 3) { let i = i; fnArr.push(function() { console.log(i); }); } i++; ... }
Is not see the point of tricks? In fact, we can understand, in each cycle are re-declare i, and i is assigned to the outer layer of the current value. (Note that ah, here is pseudo-code, easy to understand, in practice let i = i will throw exceptions)
Reprinted Source: https://www.cnblogs.com/innooo/p/10438947.html
This series is the usual reading, learning, real-world projects have new features on es6 in, with a brief summary of the hair, the purpose is to record for later review; this series is expected to contain let / const, arrows function, deconstruction, new common method, Symbol, Set & Map, Proxy, reflect, Class, Module, Iterator, Promise, Generator, async / await
let / const brought us what?
let
- Bound variable lift
(function foo() { console.log(a); let a = 1; })(); // Uncaught ReferenceError: a is not defined
To conclude that one: Before variables, we must first declare the variable declaration always before use.
- It brought the block-level scope
// es5 (function(){ if(false) { var temp = 1; } console.log(temp); // undefined })(); // es6 (function(){ if(false) { let temp = 1; } console.log(temp); // Uncaught ReferenceError: temp is not defined })();
From the code, we can clearly see let's es6 of block-level scope, the block-level scope What application do? for example:
var fnArr = []; for(var i = 0; i < 5; i++) { fnArr.push(function() { console.log(i); }); } fnArr[0](); // 5 fnArr[1](); // 5 fnArr[2](); // 5 fnArr[3](); // 5 fnArr[4](); // 5 console.log(i); // 5
Without careful analysis, the results of the implementation is not surprising that some of it? Yes, we intended for internal use in variable loop i was leaked became a global variable, and each cycle of the for loop, the variable i has not been restated, virtually every function stored in an array referenced fnArr They are the same variable i, so that led to the current results, how to make the code run in accordance with our initial ideas? Es5 commonly used term solution
var fnArr1 = []; for(var i = 0; i < 5; i++) { (function(j) { fnArr1.push(function() { console.log(j); }); })(i) } fnArr1[0](); // 0 fnArr1[1](); // 1 fnArr1[2](); // 2 fnArr1[3](); // 3 fnArr1[4](); // 4 console.log(i); // 5
Appears to be solved, here actually used the method closure, fnArr1 function references in each of j is a copy of the current time cycle i, thus solves the previous problem, but there is a problem: Variable i still get leaked to the implicit global
var fnArr1 = []; for(let i = 0; i < 5; i++) { fnArr1.push(function() { console.log(i); }); } fnArr1[0](); // 0 fnArr1[1](); // 1 fnArr1[2](); // 2 fnArr1[3](); // 3 fnArr1[4](); // 4 console.log(i); // Uncaught ReferenceError: i is not defined
OK,问题解决了,仅仅是将’var‘替换成了let,这就是let带来的便利。
- 产生暂时性死区&禁止重复声明
// 什么是禁止重复声明呢? 先不给书面解释,来看一个es5中经常的写法 (function() { var temp = 1; var temp = 2; var temp = function() { return 1; }; })();
上面这段代码执行没有任何问题,最终temp被赋值为一个函数
(function() { let temp = 1; var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declared var temp = function() { return 1; }; })();
在第三行时就抛出了一个错误:temp已经被声明,是的,let声明过的变量,是不允许再次被声明的,再给几个例子巩固一下:
(function() { var temp = 2; var temp = function() { return 1; }; let temp = 1; // Uncaught SyntaxError: Identifier 'temp' has already been declared })(); (function() { if(true) { let temp = 1; var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declared } })(); (function() { if(true) { let temp = 1; function temp() { // Uncaught SyntaxError: Identifier 'temp' has already been declared return 1; } } })();
看出来了吗?只要是在let声明所在的作用域,就不允许再次声明同名变量(包括函数声明)
var foo = 1; if(true) { foo = 2; // Uncaught ReferenceError: foo is not defined let foo; }
看到let的’霸道‘了吧?只要在let所在的作用域,同名的变量就会被let占有,不允许重复声明,同时也要遵守let的规则
- 全局变量不再作为window对象的属性
var foo = 1; (function() { bar = 2; })(); window.foo; // 1 window.bar; // 2
是的,es5中,全局变量(包括意外泄露的)都将自动被添加为window对象的属性
let foo = 1; window.foo; // undefined
一切尽在不言中。。。
const
- let所拥有的特性,const都有,同时const还有一条:const声明的变量必须进行初始化,并且不能再被重新赋值
const temp = 1; temp = 2; // Uncaught TypeError: Assignment to constant variable.
注意是不能被重新赋值,这样是比较准确的,其实const声明的变量是可以被修改的,当const声明的变量被初始化为复杂数据类型时,const声明的变量就是可变的,至于为什么,自己理解喽(变量标识符中保存的只是复杂数据类型内存地址而已。。。)
const temp = {}; temp.foo = 'aa'; // 这里没问题 temp = {foo: 'aa'}; // 这里就会抛出异常
for循环中的变量声明
前面在记录let块级作用域的时候,我们使用了一个for循环的例子,这里我们不妨试着解析一下for循环的执行过程
var fnArr = []; for(var i = 0; i < 3; i++) { fnArr.push(function() { console.log(i); }); } // 伪代码 var fnArr; fnArr = []; { var i; i = 0; if(i < 3) { fnArr.push(function() { console.log(i); }) } i++; if(i < 3) { fnArr.push(function() { console.log(i); }); } i++; ... }
这里可惜清晰得看到所有的i都是一个i。。。那使用了let以后呢?
var fnArr = []; for(let i = 0; i < 3; i++) { fnArr.push(function() { console.log(i); }); } // 伪代码 var fnArr; fnArr = []; { let i; i = 0; if(i < 3) { let i = i; fnArr.push(function() { console.log(i); }) } i++; if(i < 3) { let i = i; fnArr.push(function() { console.log(i); }); } i++; ... }
Is not see the point of tricks? In fact, we can understand, in each cycle are re-declare i, and i is assigned to the outer layer of the current value. (Note that ah, here is pseudo-code, easy to understand, in practice let i = i will throw exceptions)