我们很难及时得知JavaScript(ECMAScript)中的最新功能,同时找到相关的示例代码更加困难。在此总结了一些ECMAScript的一些新特性
1. Array.prototype.includes
// ES6 Array.prototype.includes
// includes是Array上的一个简单实例方法,能帮助我们轻松查找某项是否存在于数组中(处理 NaN的方式与 indexOf不同)。
const arr = [1,2,3,4,NaN];
// indexOf
if(arr.indexOf(3)>=0){
console.log('indexOf: true')
}
// inclues
if(arr.includes(3)){
console.log('includes: true')
}
arr.indexOf(NaN) // -1 不存在arr中
arr.includes(NaN) // true 存在arr中
2. 幂运算符
// ES6特性
// 加法和减法等数学运算分别对应 +和 -运算符。 同样,**运算符通常用于指数运算。 在ECMAScript 2016中,引入 **来代替Math.pow。
console.log(Math.pow(7,2)) // 49
console.log(7**2) // 49
3 Object.values()
// ES7特性
// Object.values()是一个与Object.keys()类似的新函数,不过它返回的是Object自身属性的所有值,不包括原型链中的任何值。
const animal = {cat:1,dog:2,pig:3};
// ES6 获取对象的值
const values1 = Object.keys(animal).map(key=>animal[key])
console.log(values1) // [1,2,3]
// ES7 获取对象的值
const values2 = Object.values(animal);
console.log(values2) // [1,2,3]
4.Object.entries()
// ES7特性
/**
* Object.entries()与Object.keys相关,但它并不是仅返回键,而是以数组方式返回键和值。
* 这样一来,在循环中使用对象或将对象转换为Maps等操作将会变得非常简单。
*
* */
const animal = {cat:1,dog:2,pig:3};
// ES6
Object.keys(animal).forEach(function(key){
console.log('key: '+key+' value: '+ animal[key])
})
console.log('-----------------')
// ES7
for(let [key,value] of Object.entries(animal)){
console.log(`key: ${key} value: ${value}`)
}
5.字符串填充
// ES7新特性
/**
* String 中添加了两个实例方法—— String.prototype.padStart和String.prototype.padEnd,
* 允许将空字符串或其他字符串附加/前置到原始字符串的开头或结尾。
*/
console.log('5'.padStart(10)) // 5
console.log('5'.padStart(10,'=')) // =========5
console.log('5'.padEnd(10)) // 5
console.log('5'.padEnd(10,'*')) // 5*********
6.Object.getOwnPropertyDescriptors
// ES7新特性
/**
* 此方法返回给定对象的所有属性的全部详细信息(包括getter方法 get和 setter方法 set)
* 添加它的主要目的是允许浅层拷贝/克隆对象到另一个对象,该对象也复制getter和setter函数而不是Object.assign。
* Object.assign用于浅层拷贝除了原始源对象的getter和setter函数之外的所有细节。(注意)
*/
let Animal = {
cat:1,
dog:2,
pig:3,
get Name(){
return this.name;
},
set Name(name){
this.name = name
}
}
console.log(Animal)
console.log(Object.getOwnPropertyDescriptor(Animal,'Name'))
let xht = Object.assign({},Animal); // 浅拷贝 没有拷贝get set函数
console.log('浅拷贝',xht)
console.log('-------------有了Object.getOwnPropertyDescriptor之后')
const newXht = Object.defineProperties({},Object.getOwnPropertyDescriptor(Animal));
console.log(Object.getOwnPropertyDescriptor(newXht,'Name'))
console.log(newXht) // 可以把set get函数拷贝过来
7.在函数参数中添加尾随逗号
// ES7新特性
/**
* 在函数参数中添加尾随逗号
* 这是一个次要更新,允许我们在最后一个函数参数后面有逗号。 为什么?
* 帮助使用像git blame这样的工具来确保只有新的开发人员的代码被标注。
*/
function Person(name,age,){
this.name = name;
this.age = age;
}
console.log(Person)
8. Async/Await
// ES7 新特性
/**
* 到目前为止,这是最重要和最有用的功能。 异步函数允许我们不必处理回调并使整个代码看起来很简单
* async关键字告诉JavaScript编译器以不同方式处理函数。
* 只要到达该函数中的await关键字,编译器就会暂停。
* 它假定await之后的表达式返回一个promise并等待,直到promise被解决或被拒绝,然后才进一步移动。
*/
function getUser(userId){
return new Promise(resolve=>{
setTimeout(()=>{
resolve('xht')
},1000)
})
}
function getBalance(user){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(user=='xht'){
resolve('$1000')
}else{
reject('unknown user')
}
},1000)
})
}
// ES6
function getAccount(userId){
getUser(userId)
.then(getBalance)
.then(account=>{
console.log(account)
})
}
// ES7
async function getAccount2(userId) {
let user = await getUser(userId);
let account = await getBalance(user);
console.log(account)
}
8.2异步函数本身返回一个Promise
function doubleAfterSec(param){
return new Promise(resolve=>{
setTimeout(resolve(param*2),1000);
})
}
async function doubleAndAdd(a,b) {
a = await doubleAfterSec(a);
b = await doubleAfterSec(b);
return a+b;
}
// 结果
doubleAndAdd(1,2).then((value)=>{
console.log(value)
})
8.3并行调用 async/await
/**
* 在前面的例子中,我们调用了两次await,每次会等待一秒钟(总共2秒)。
* 不过我们可以并行化处理它,因为a和b使用Promise.all相互依赖
*/
function doubleAfterSec(param){
return new Promise(resolve=>{
setTimeout(resolve(param*2),1000);
})
}
async function doubleAndAdd(a,b) {
[a,b] = await Promise.all([doubleAfterSec(a),doubleAfterSec(b)])
return a+b;
}
// 结果
doubleAndAdd(1,2).then((value)=>{
console.log(value)
})
8.4async/await错误处理功能
/**
* 在函数中使用try catch
*/
function doubleAfterSec(param) {
return new Promise(resolve => {
setTimeout(resolve(param * 2), 1000);
})
}
async function doubleAndAdd(a, b) {
try {
a = await doubleAfterSec(a);
b = await doubleAfterSec(b);
} catch (e) {
console.log(e)
}
return a + b;
}
// 结果
doubleAndAdd(1, 2).then((value) => {
console.log(value)
})
9.对象的Spread属性
// ES8新特性
let {firstName,age,...remaining} = {
firstName:'xie',
lastName:'haitao',
age:20,
sex:'男'
}
console.log(firstName) // xie
console.log(age) // 20
console.log(remaining) // {lastName:'haitao',sex:'男'}
10.Promise.prototype.finally()
// ES8新特性
let {firstName,age,...remaining} = {
firstName:'xie',
lastName:'haitao',
age:20,
sex:'男'
}
console.log(firstName) // xie
console.log(age) // 20
console.log(remaining) // {lastName:'haitao',sex:'男'}
11.异步迭代
// ES8新特性
/**
* 这是一个非常有用的功能。 它允许我们轻松的创建异步代码循环!
* 此功能添加了一个新的“for-await-of”循环,允许我们在循环中调用返回promises(或带有一堆promise的Arrays)的异步函数。
* 更酷的是循环会在在进行下一个循环之前等待每个Promise
*/
const promises = [
new Promise(resolve=>resolve(1)),
new Promise(resolve=>resolve(2)),
new Promise(resolve=>resolve(3))
]
// 以前写法
async function test1() {
for(const obj of promises){
console.log(obj)
}
}
async function test2() {
for await(const obj of promises){
console.log(obj)
}
}
test1() // promise,promise,promise
test2() // 1,2,3
来自:https://mp.weixin.qq.com/s/YoISN0TRxOQlj0EhtQVl2A
https://mp.weixin.qq.com/s/6RdC28HsMvs1OSPAJzMemg
网友评论