1.函数参数默认值

在ES6之前,需要给函数参数设置默认值,通常使用的是短路运算符;使用ES6可以对参数直接赋值。

1
2
3
function fn(num=10, name='user'){
//...
}

2.模板字符串

1
2
3
var name = 'Bob';
var speak = `My name is ${name}`;
// My name is Bob

3.多行字符串

在ES6之前,多行字符串需要用+号和换行符进行拼接;ES6可以直接把字符放到反引号里面即可。

1
2
3
4
5
var roadPoem = `Then took the other, as just as fair,
And having perhaps the better claim
Because it was grassy and wanted wear,
Though as for that the passing there
Had worn them really about the same.`

4.结构赋值

在ES6之前,获取对象里面的值需要通过索引或者键值一个一个获取;ES6中的结构赋值可以更加高效的获取。

1
2
3
4
5
6
7
8
var obj={
people:{
name:'lili',age:18
}
};
var {name, age} = obj.people;
console.log(name);
// lili

5.对象属性简写

在ES6之前,对象必须包含属性和值;ES6中可以直接写变量。

1
2
3
4
5
var name = 'Bob';
var speak = function(){
//...
};
var obj = {name, speak};

6.箭头函数

在ES6之前,普通函数的this指向调用时所在的对象。

1
2
3
4
5
6
function fn(){
console.log(this.id);
}
var id = 1;
fn(); // 1
fn.call({id: 6}); // 6

使用ES6的箭头函数,this指向定义时所在的对象,而不是调用时所在的对象。

1
2
3
4
5
6
var fn = () => {
console.log(this.id);
};
var id = 1;
fn(); // 1
fn.call({id: 6}); // 1

7.Promise

不使用ES6的话,需要嵌套多个setTimeout

1
2
3
4
5
6
setTimeout(function(){
console.log('hello');
setTimeout(function(){
console.log('Promise');
},1000)
},1000)

ES6使用两个then是异步编程串行化。

1
2
3
4
5
6
7
8
9
var wait1s = new Promise(function(resolve, rejecct){
setTimeout(resolve, 1000);
})
wait1s.then(function(){
console.log('hello');
return wait1s;
}).then(function(){
console.log('Promise');
})

8.let和const声明变量

ES6引入新的关键字声明变量和常量letconst,与var的区别如下:

var是最近的函数作用域,let是最近的块级作用域,这个要比函数作用域小。

1
2
3
4
5
6
7
8
(function(){
{
var num1 = 666;
let num2 = 999;
}
console.log(num1); // 666
console.log(num2); // Uncaught ReferenceError: num2 is not defined
})()

var定义后可以修改,初始化未赋值输出undefined;let定义后修改报错:Uncaught SyntaxError: Identifier ‘xxx’ has already been declared,初始化未赋值输出undefined。

如果在函数的for语句里面使用var定义,var在整个函数内有效;如果使用let定义,let在for语句里面有效,之外无效。

1
2
3
4
5
6
7
8
9
10
11
12
(function(){
var len = 5;
for(var i = 0; i < len; i++ ){
console.log(i); // 0,1,2,3,4
}
console.log(i); // 5

for(let n = 0; n < len; n++){
console.log(n); // 0,1,2,3,4
}
console.log(n); // Uncaught ReferenceError: n is not defined
})()

9.class类

在ES6之前使用构造函数方式。

1
2
3
4
5
6
7
8
9
function People(name, age){
this.name = name;
this.age = age;
this.speaking = function(){
return 'My name is' + this.name;
};
}
var boy = new People('Bob', 18);
console.log(boy.speaking()); // 'My name is Bob'

ES6使用class定义类,更加规范。

1
2
3
4
5
6
7
8
9
10
11
class People{
constructor(name, age){
this.name = name;
this.age = age;
}
speaking(){
return 'My name is' + this.name;
}
}
var girl = new People('Lina', 19);
console.log(girl.speaking()); // 'My name is Lina'

10.模块化

在ES6之前,模块化一般采用Common.js和AMD规范,使用module.exports={}导出相关的模块,使用var module = require('module.js');引入模块。ES6使用export和import关键字导出和导入模块。

1
2
3
4
5
6
7
8
9
10
11
12
// 导出模块
var obj = {
attribute: 'value',
fn: function(){
console.log(666);
}
};
export default obj;

// 导入上面的模块
import {attribute, fn} from 'module';
fn(); // 666

11.includes()、values()、entries()方法

includes()检测数组是否存在某个元素

1
2
var arr = [1,2,8,6,4]; 
arr.includes(4); // true

ES6新增了与keys()配套的方法values()用于遍历对象的值

1
2
3
4
var obj = {name: 'li', age: 23, country: 'USA'};
Object.values(obj).forEach(function(v){
console.log(v); // li, 23, USA
})

entries()用于遍历对象的键和值

1
2
3
4
var obj = {name: 'li', age: 23, country: 'USA'};
Object.entries(obj).forEach(function([k,v]){
console.log(k + "|" + v); // name|li, age|23, country|USA
})

12.Async/Await

用Promise实现异步操作需要不断地链式回调,有时候一个异步的操作需要等到另一个异步操作完后才开始执行,这时候就陷入了层层的嵌套中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 用nodejs读取两个文件,先读取第一个文件处理后在读取第二个文件。
const fs = require('fs');

const readFn = function(fileName){
return new Promise(function(resolve, reject){
fs.readFile(fileName, function(error, data){
if(error) return reject(error);
resolve(data);
})
})
};
// 假定文件内容为文件名
readFn('file1.txt') // 绝对路径
.then(function(data1){
console.log(data1 + '666'); // file1.txt666
return data1 + '666';
}).then(function(data2){
return readFn('file2.txt').then(function(data){
console.log(data2 + data); // file1.txt666file2.txt
return data2 + data;
})
}).then(function(data3){
console.log(data3 + '999'); // file1.txt666file2.txt999
}).catch(function(err){
console.log('error');
})

async/await是基于Promise实现的,它不能用于普通的回调函数,它使得异步代码看起来像同步代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const fs = require('fs');

const readFn = function(fileName){
return new Promise(function(resolve, reject){
fs.readFile(fileName, function(error, data){
if(error) return reject(error);
resolve(data);
})
})
};

const asyncReadFile = async function(){
const f1 = await readFn('file1.txt');
const f2 = await readFn('file2.txt');
console.log(f1.toString()); // file1.text
console.log(f2.toString()); // file2.text
console.log(f1.toString() + f2.toString()); // file1.textfile2.txt
};

asyncReadFile();