ES6 慢慢学~
ES5 只有两种声明变量的方法:var
命令和function
命令。javascript
ES6 除了添加let
命令和const
命令,另外两种声明变量的方法:import
命令和class
命令。java
因此,ES6一共有6 种声明变量的方法。es6
var
命令能够声明变量function
命令声明函数,后跟一组参数及函数体let
命令用于声明变量const
命令声明一个只读的常量export
命令显式指定输出的代码,再经过import
命令输入class
关键字能够定义类let
命令和const
命令所声明的变量or常量只在它所在的代码块有效。数组
const
实际上保证的,并非变量的值不得改动,而是变量指向的按个内存地址所保存的数据不得改动。数据结构
- 对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,所以等同于常量。
- 对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针。
const
只能保证这个指针是固定的(即老是指向另外一个固定的地址),至于它指向的数据结构是否是可变的,就彻底不能控制了。const
只声明不赋值,就会报错。
for (let i = 0; i < 4; i++) { // ... } console.log(i); // ReferenceError: i is not defined
const student = {}; // 能够添加一个属性 student.name = '朝霞的世界'; // 将 student 指向另外一个对象,就会报错 student = {}; // TypeError: "student" is read-only
ES5 只有全局做用域和函数做用域,没有块级做用域,这样会有一些不合理的场景。函数
- 内层变量可能会覆盖外层变量
- 用来计数的循环变量泄露为全局变量
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'zhaoxiajingjing'; } } f(); // undefined
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
ES6 新增了块级做用域,容许任意嵌套。使得自执行匿名函数表达式就再也不必要了。spa
{{{{ {let insane = 'zhaoxiajingjing'} console.log(insane); // 报错 }}}};
// 自执行匿名函数 (function () { var tmp = ...; }()); // 块级做用域写法 { let tmp = ...; }
只要块级做用域内存在let
命令或const
命令,它所声明的变量或常量就“绑定”(binding)这个区域,再也不受外部影响。3d
在代码块内,使用let
命令声明变量以前,该变量都是不可用的。这在语法上,称为:暂时性死区(temporal dead zone,简称TDZ)指针
if (true) { // TDZ开始 tmp = 'zhaoxiajingjing'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
let
和const
PK var
- 有效范围:
var
声明的变量,会声明到全局,污染全局变量- 变量提高:
var
声明的变量,能够在声明以前调用- 做用域:使用
var
的做用域有全局做用域、函数做用域- 重复声明:
var
能重复声明
let
和const
只在声明所在的块级做用域内有效var
声明的变量,会声明到全局,污染全局变量
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 window.a[4](); // 10 window.i; // 10
上面代码中,变量 i
是var
命令声明的,在全局范围内有效,因此全局只有一个变量i
。能够在window
上访问并获取到值。code
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6 window.a[4](); // 4 window.i; // undefined
上面代码中,变量i
是let
声明的,当前的i
只在本轮循环有效,因此每一次循环的i
都是一个新的变量,因此每次输出的值不同。
let
声明的变量仅在块级做用域内有效,因此在window
上i
的值是undefined
。
for
循环还有一个特别之处,就是设置循环变量的那部分是一个父做用域,而循环体内部是一个单独的子做用域。
for (let i = 0; i < 3; i++) { let i = 'zhaoxiajingjing'; console.log(i); } // zhaoxiajingjing // zhaoxiajingjing // zhaoxiajingjing
let
和const
声明的变量or常量不会提高,必定要在声明后使用,不然报错var
声明的变量,能够在声明以前调用,值为undefined
// var 的状况 console.log(a); // 输出undefined var a = 2; // let 的状况 console.log(b); // 报错ReferenceError let b = 2;
let
和const
能够在块级做用域中使用- 使用
var
的做用域有全局做用域、函数做用域
{ var a = 'hello'; let gzh = 'zhaoxiajingjing'; } console.log(a); // hello console.log(gzh); // ReferenceError: gzh is not defined
let
和const
不容许在相同做用域内,重复声明同一个变量var
能重复声明
// 报错 function f(){ let gongzhonghao = 'zhaoxiajingjing'; var gongzhonghao = 'zhaoxiajingjing'; } f();
// 不报错 function f(){ var gongzhonghao = 'zhaoxiajingjing'; var gongzhonghao = 'zhaoxiajingjing'; } f();
// 报错 function f(args){ let args = 'zhaoxiajingjing'; } f();
// 不报错 function f(args){ { let args = 'zhaoxiajingjing'; } } f();
typeof
有什么影响?参考:ECMAScript 6 入门
http://es6.ruanyifeng.com/#do...