过年在家闲着没事,来看看ES6,选了阮一峰大大的《ES6 标准入门》这本书,了解一下新的js规范。这里做一下读书笔记。
ECMAScript 6 须知
目前各大浏览器的自新版本应该都支持ES6了,并且Node.js对ES6的支持度比浏览器还高,通过Node可以体验更多ES6的特性。
Babel转码器
Babel是个ES6转码器,可以将ES6代码转换为ES5代码,从而在现有环境执行。也就是说,你可以用ES6的方式编写程序,又不用担心现有环境是否支持。
还有个Traceur转码器也是一样的效果。
let和const命令
let命令
基本用法: let用来都声明变量,类似var,但是所生命的变量,只在let命令所在的代码块中有效。for循环计数器的i,就很适合用let命令,这样i只在for循环内有效。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
let不详var那样会发生“变量提升”现象,所以变量一定要先声明后使用,否则会报错。
变量提升简单来说,就是自动把变量的定义提前解析,这样,即使先使用,后定义变量,程序也可以正常运行。但是这里要注意,变量提升,只是提前声明了变量,并没有赋值。见下例:
console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError
var foo = 2;
let bar = 2;
var出来的foo变量提升了,但是提升只是定义,并不赋值,所以是undefined;而let bar 则不存在变量提升,会直接报错
函数只有声明形式才能提升。匿名函数赋值不能提升。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。在语法上成为“暂时性死区(TDZ)”
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
若在let声明变量前使用typeof,也会报错。完全不声明反而不会报错。
let不允许重复声明
ES6的块级作用域
let实际上为js新增了块级作用域。
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
上边的函数有两个代码块,都声明了n,运行后输出5,这说明外层代码块不受内层代码块的影响,如果这里用var,最后输出的n就是10。
const 命令
const 声明一个只读的常量,一旦声明,就要立即初始化复制,然后常量的值不能改变。
const的作用域跟let相同: 只在声明所在的块级作用域内有效。并且没有变量提升,一定要先声明后使用。且不可重复声明
const声明的对象,只是指向对象的地址不变,对象本身是可变的。但不能重新赋值
const声明的数组,可以用push等方法,但是不能重新赋值
从ES6开始,全局变量将逐步与全局对象的属性脱钩。let,const,class声明的全局变量,不再属于全局对象的属性:
var a = 1
window.a // 1
let b = 1;
window.b // undefined
变量的解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
如:
// ES5 赋值
var a = 1;
var b = 2;