ES6、ES7、ES8学习指南(三)includes()、指数操作符、async/await、Object.values()、Object.entries()

版本 发布时间 新特性
ES5 2009年11月 扩展了Object、Array、Function的功能等
ES6 2015年6月 类、模块化、箭头函数、函数参数默认值等
ES7 2016年3月 includes,指数操作符
ES8 2017年6月 async/await,Object.values(),Object.entries(),String padding等

ES7特性

在ES6之后,ES的发布频率更加频繁,基本每年一次,所有自ES6之后,每个新版本的特性的数量就比较少。

  • includes()
  • 指数操作符

1.Array.prototype.includes()

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存在');
}

2.指数操作符

在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
  • Object.values()
  • Object.entries()
  • String padding
  • 函数参数列表结尾允许逗号
  • Object.getOwnPropertyDescriptors()

1.async/await

在ES8中加入了对async/await的支持,也就是我们所说的异步函数

使用async/await和不使用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

async/await的几种应用场景

获取异步函数的返回值

异步函数本身返回一个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);
	});
}

async/await在并发场景中的应用

对于上述的例子,我们调用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/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);
	});
}

2.Object.values()

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的步骤。

3.Object.entries

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

其它几个属性不常用,此处步详细介绍。

你可能感兴趣的:(ES6、ES7、ES8学习指南(三)includes()、指数操作符、async/await、Object.values()、Object.entries())