版本 | 发布时间 | 新特性 |
---|---|---|
ES5 | 2009年11月 | 扩展了Object、Array、Function的功能等 |
ES6 | 2015年6月 | 类、模块化、箭头函数、函数参数默认值等 |
ES7 | 2016年3月 | includes,指数操作符 |
ES8 | 2017年6月 | async/await,Object.values(),Object.entries(),String padding等 |
在ES6之后,ES的发布频率更加频繁,基本每年一次,所有自ES6之后,每个新版本的特性的数量就比较少。
includes()
函数用来判断一个数组是否包含一个指定的值,如果包含则返回true
,否则返回false
。
includes
函数与indexOf
函数很相似。下面两个表达式是等价的:
arr.includes(x)
arr.indexOf(x) >= 0
判断数字中是否包含某个元素:
在ES7之前的做法
使用indexOf()验证数字中是否存在某个元素,这是需要根据返回值是否为-1来判断:
let arr = ['react','angular','vue'];
if(arr.indexOf('react') !== -1){
console.log('react存在');
}
使用includes()验证数组中是否存在某个元素
let arr = ['react','angular','vue'];
if(arr.includes('react')){
console.log('react存在');
}
在ES7中引入了指数运算符**
,**
具有与Math.pow(..)
等效的计算结果。
不使用指数操作符
使用自定义的递归函数calculateExponent
或者Math.pow()
进行指数运算:
function calculateExponent(base, exponent){
if(exponent == 1){
return base;
}
else{
return base * calculateExponent(base, exponent - 1);
}
}
console.log(calculateExponent);//输出1024
console.log(Math.pow(2, 10));//输出1024
使用**
console.log(2**10);//输出1024
在ES8中加入了对async/await
的支持,也就是我们所说的异步函数
。
login(userName){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve('1001');
},600);
});
}
getData(userId){
return new Promise((resolve,reject) => {
setTimeout(() => {
if(userId === '1001'){
resolve('Success');
}else{
reject('Fail');
}
},600);
});
}
//不使用async/await ES7
doLogin(userName){
this.login(userName)
.then(this.getData)
.then(result => {
console.log(result);
})
}
//使用async/await ES8
async doLogin2(userName){
const userId = await this.login(userName);
const result = await this.getData(userId);
}
this.doLogin();//Success
this.doLogin2();//Success
异步函数本身返回一个Promise
,所以我们可以通过then
来获取异步函数的返回值。
async function charCountAdd(data1, data2){
const d1 = await charCount(data1);
const d2 = await charCount(data2);
return d1 + d2;
}
charCountAdd('Hello','Hi').then(console.log);//通过then获取异步函数的返回值。
function charCount(data){
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(data.length);
},1000);
});
}
对于上述的例子,我们调用await两次,每次都是等待1秒一共2秒,效率较低,而且两次await的调用并没有依赖关系,那能不能让其并发执行呢?答案是可以的。下面通过Promise.all
来实现await
的并发调用。
async function charCountAdd(data1,data2){
const [d1,d2] = await Promise.all([charCount(data1),charCount(data2)]);
return d1 + d2;
}
charCountAdd('Hello','Hi').then(console.lgo);
function charCount(data){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data.length);
},1000);
});
}
通过上述代码我们实现了两次charCount
的并发调用,Promise.all
接受的是一个数组,它可以将数组中的promise对象并发执行;
第一种:捕捉整个async/await函数的错误
async function charCountAdd(data1,data2){
const d1 = await charCount(data1);
const d2 = await charCount(data2);
return d1 + d2;
}
charCountAdd('Hello','Hi')
.then(console.log)
.catch(console.log);//捕捉整个async/await函数的错误
这种方式可以捕捉整个charCountAdd
运行过程中出现的错误,错误可能是由charCountAdd
本身产生的,也可能是由对data1
的计算中或data2
的计算中产生的。
第二种:捕捉单个的await表达式的错误
async function charCountAdd(data1,data2){
const d1 = await charCount(data1)
.catch(e=>console.log('d1 is null'));
const d2 = await charCount(data2)
.catch(e=>console.log('d2 is null'));
return d1 + d2;
}
charCountAdd('Hello','Hi').then(console.log);
如果既要捕捉每一个await
表达式的错误,又要捕捉整个charCountAdd
函数的错误,可以在调用charCountAdd
的时候加个catch
。
charCountAdd('Hello','Hi')
.then(console.log)
.catch(console.log);//捕捉整个asnyc/await函数的错误
第三种:同时捕捉多个的await表达式的错误
async function charCountAdd(data1,data2){
let d1,d2;
try{
d1 = await charCount(data1);
d2 = await charCount(data2);
}catch(e){
console.log('d1 is null');
}
return d1 + d2;
}
charCountAdd('Hello','Hi')
.then(console.log);
function charCount(data){
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(data.length);
},1000);
});
}
object.values()
是一个与Object.keys()
类似的新函数,但返回的是Object自身属性的所有值,不包括继承的值。
假设我们要遍历如下对象obj
的所有值:
const obj = {a: 1, b: 2, c: 3};
不使用Object.value(): ES7
const vals = Object.keys(obj).map(key => obj[key]);
console.log(vals);//[1, 2, 3]
使用Object.values():ES8
const values = Object.values(obj1);
console.log(values);//[1, 2, 3]
object.values()
为我们省去了遍历key,并根据这些key获取value的步骤。
Object.entries()函数返回一个给定对象自身可枚举属性的键值对的数组。
接下来我们来遍历上文中的obj对象的所有属性的key和value:
不用Object.entries():ES7
Object.keys(obj).forEach(key => {
console.log('key:' + key + ' value:' + obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3
使用Object.entries():ES8
for(let [key,value] of Object.entries(obj1)){
console.log(`key:${key} value:${value}`);
}
//key:a value:1
//key:b value:2
//key:c value:3
其它几个属性不常用,此处步详细介绍。