尚硅谷ES7-ES11新特性(66th)

本文介绍了ECMAScript 7到11的新特性,包括Array.prototype.includes、指数运算符、async/await异步处理、Object.values和Object.entries方法。重点讲解了async函数和await关键字如何简化异步代码,以及BigInt新数字类型的应用。通过实例展示了如何使用这些新特性进行文件读取和Ajax请求,使代码更易读、更直观。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、ECMASript 7 新特性

1. Array.prototype.includes

includes 方法用来检测数组中是否包含某个元素,返回布尔类型值。

2. 指数运算符

在 ES7 中引入指数运算符 **,用来实现幂运算,功能与 Math.pow(a, b) 结果相同。

2 ** 3 // 8
Math.pow(2, 3) // 8

二、ECMAScript 8 新特性

1. async 和 await(重要)

asyncawait 两种语法结合可以让异步代码像同步代码一样。(即:看起来是同步的,实质上是异步的。)

先从字面意思理解,async 意为异步,可以用于声明一个函数前,该函数是异步的。await 意为等待,即等待一个异步方法完成。

1.1 async

async 声明function的函数成为 async 函数,语法:

async function funcName() {
    //statements 
}

async 内部可以使用 await,也可以不使用。 async 函数的返回值是一个 Promise 对象,因此执行这个函数时,可以使用 thencatch 方法。 根据 函数体内部 的返回值, async 函数返回值具体情况如下:

1、函数体内不返回任何值,则 async 函数返回值为一个成功(fulfilled)Promise 对象,状态值为 undefined

let a = async function() {}
let res = a()
console.log(res)
// Promise{<fullfilled>: undefined}

2、返回结果不是一个 Promise ,则 async 函数返回值为一个成功(fulfilled)Promise 对象,状态值为这个内部返回值。

let a = async function () {
  return 'hello'
}
let res = a()
console.log(res) 
// Promise{<fullfilled>: 'hello'}

3、内部抛出错误,则 async 函数返回值为一个失败的 Promise 对象。

let a = async function foo() {
  throw new Error('出错了')
}
a().catch(reason => {
  console.log(reason)
})

4、若函数内部返回值是一个 Promise 对象,则 async 函数返回值的状态取决于这个 Promise 对象。

let a = async function () {
  return new Promise((resolve, reject) => {
    resolve("成功")
  })
}
a().then(value => {
  console.log(value)
})

1.2 await

await 相当于一个运算符,右边接一个值。一般为一个 Promise 对象,也可以是一个非 Promise 类型。当右接一个非 Promise 类型,await 表达式返回的值就是这个值;当右接一个 Promise 对象,则 await 表达式会阻塞后面的代码,等待当前 Promise 对象 resolve 的值。

综合 asyncawait 而言。await 必须结合 async 使用,而 async 则不一定需要 awaitasync 会将其后的函数的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,然后返回 resolve 的结果。当这个 Promise 失败或者抛出异常时,需要时使用 try-catch 捕获处理。

Promise 使用链式调用解决了传统方式回调地狱的问题,而 async-await 又进一步优化了代码的可读性。

const p = new Promise((resolve, reject)=>{
  resolve('成功')
})
async function main() {
  let res = await p
  console.log(res)
}
main()
// '成功'
const p = new Promise((resolve, reject)=>{
  reject('失败')
})
async function main() {
  try {
    let res = await p
    console.log(res)
  } catch(e) {
    console.log(e)
  }
}
main()
// '失败'

1.3 综合应用-读取文件

需求:先读取用户数据 user,然后读取订单数据 order,最后读取商品数据 goods。

对于这种异步操作很容易想到使用 Promise,代码如下:

const fs = require('fs')

let p = new Promise((resolve, reject) => {
  fs.readFile('./files/user.md', (err, data) => {
    if (err) reject(err)
    resolve(data)
  })
})

p.then(value => {
  return new Promise((resolve, rejecet) => {
    fs.readFile('./files/order.md', (err, data) => {
      if (err) rejecet(err)
      resolve([value, data])
    })
  })
}, reason => {
  console.log(reason)
}).then(value => {
  return new Promise((resolve, reject) => {
    fs.readFile('./files/goods.md', (err, data) => {
      if (err) reject(err)
      value.push(data)
      resolve(value)
    })
  })
}, reason => {
  console.log(reason)
}).then(value => {
  console.log(value.join('\n'))
}, reason => {
  console.log(reason)
})

但是,使用 Promise 链式调用虽然避免了回调地狱,但这种链式调用过多难免引起代码复杂,看起来不直观。可以使用 asyncawait 方法优化,代码如下:

const fs = require('fs')

function readUser() {
  return new Promise((resolve, reject) => {
    fs.readFile('./files/user.md', (err, data) => {
      if (err) reject(err)
      resolve(data)
    })
  })
}

function readOrder() {
  return new Promise((resolve, reject) => {
    fs.readFile('./files/order.md', (err, data) => {
      if (err) reject(err)
      resolve(data)
    })
  })
}

function readGoods() {
  return new Promise((resolve, reject) => {
    fs.readFile('./files/goods.md', (err, data) => {
      if (err) reject(err)
      resolve(data)
    })
  })
}

async function read() {
  let user = await readUser()
  let order = await readOrder()
  let goods = await readGoods()
  console.log([user, order, goods].join('\n'))
}

read()

这样,代码看起来很直观,就好像是同步代码一样,实际上是异步操作。

1.4 综合应用-封装ajax

function sendAjax(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('get', url)
    xhr.send()
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(JSON.parse(xhr.response))
        }
        reject(xhr.status)
      }
    }
  })
}

async function main() {
  let res = await sendAjax('http://poetry.apiopen.top/sentences')  //直接得到promise成功状态的值
  console.log(res)
}

main()

2. Object.values 和 Object.entries

1、Object.values() 方法返回一个给定对象的所有可枚举属性值的数组,类似于 Object.keys(),只是前者返回属性值,后者返回键值组合的数组。

let obj = {
  a: 1,
  b: {1:2},
  c: [1,2,3]
}
console.log(Object.values(obj))
// [1, {1: 2}, [1,2,3]]
console.log(Object.keys(obj))
// ['a', 'b', 'c']

2、Object.entries() 方法返回一个给定对象自身可遍历属性 [key,value] 的数组(数组元素也是一个个的数组的数组)

const obj = {a: 1, b: 2, c: 3};
console.log(Object.entries(obj))
// [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]

返回的是一个数组,这样就可以使用 for...of 遍历了。

const obj = { a: 1, b: 2, c: 3 };
for (let [k, v] of Object.entries(obj)) {
  console.log(k, v)
}

三、ECMAScript 11 新特性

1、BigInt(新的数字类型)

BigInt 是一种特殊的数字类型,它提供了对任意长度整数的支持。

创建 bigint 的方式有两种:在一个整数字面量后面加 n 或者调用 BigInt 函数,该函数从字符串、数字等中生成 bigint

let n1 = 123n
let n2 = 456n
let n3 = BigInt(789)
console.log(typeof n1) // bigint
console.log(n1+n2) // 579n
console.log(n2+n3) // 1245n

比较运算符:

例如 < 和 >,使用它们来对 bigintnumber 类型的数字进行比较没有问题:

alert( 2n > 1n ); // true
alert( 2n > 1 ); // true

但是请注意,由于 number 和 bigint 属于不同类型,它们可能在进行 == 比较时相等,但在进行 ===(严格相等)比较时不相等

alert( 1 == 1n ); // true
alert( 1 === 1n ); // false

2、globalThis

全局对象提供可在任何地方使用的变量和函数。默认情况下,这些全局变量内置于语言或环境中。
在浏览器中,它的名字是 window,对 Node.js 而言,它的名字是 global,其它环境可能用的是别的名字。
ES11中 globalThis 被作为全局对象的标准名称加入到了 JavaScript 中,所有环境都应该支持该名称。所有主流浏览器都支持它。

使用场景: 假设我们的环境是浏览器,我们将使用 window。如果你的脚本可能会用来在其他环境中运行,则最好使用 globalThis

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值