JavaScript ES7~ES11新增语法相关个人总结

ES7

- includes

includes方法用来检测数组中是否包含某个元素,返回布尔类型值
类似于indexOf,只不过indexOf当找不到元素时,返回的是-1

代码例:

// includes
const arr = ['a', 'b', 'c', 'd']

console.log(arr.includes('b')) // true
console.log(arr.includes('f')) // false

- ** 幂运算

在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同

代码例:

// **

// 2的10次方
console.log(2 ** 10) // 1024
// Math.pow方法
console.log(Math.pow(2, 10)) // 1024

ES8

- async和await

* async函数

async 函数的返回值为 promise 对象
promise 对象的结果由 async 函数执行的返回值决定

代码例:

// async函数,返回结果是一个Promise对象
// 而Promise对象内的结果(状态、值)由async函数内执行的返回值决定
// 返回值有这么几种情况:
// 1. 非Promise对象
async function fn1(){
  return '字符串'
}
const result1 = fn1()
console.log(result1) // Promise对象状态:resolved,值:'字符串'

// 2. 抛出错误
async function fn2(){
  throw '出错了'
}
const result2 = fn2()
console.log(result2) // Promise对象状态:rejected,值:'出错了'

// 3. Promise对象
async function fn3(){
  return new Promise((resolve, reject)=>{
  	// resolve('成功')
  	// reject('失败')
  })
}
const result3 = fn3()
console.log(result3)
// Promise对象状态:和async函数fn3内Promise对象的执行结果一致
// 执行了哪个(resolve或reject),状态就是哪个
// Promise对象值:执行resolve或reject方法时所传入的参数

* await表达式

await 必须写在 async 函数中
await 右侧的表达式一般为 promise 对象
await 返回的是 promise 成功的值
await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理

代码例:

// 创建Promise对象
const p = new Promise((resolve, reject)=>{
  resolve('用户数据')
  // reject('失败了')
})

// await 放在async函数中
async function fn() {
  try{
    // Promise对象成功,执行此处
    let result = await p
    console.log(result) // '用户数据'
  } catch(e) {
    // Promise对象失败,执行此处
    console.log(e)
  }
}

// 调用函数
fn()

- 对象方法扩展

代码例:

// 声明对象
const obj = {
  name: 'sky',
  arr1: ['a', 'b', 'c', 'd'],
  arr2: [1, 2, 3, 4]
}
// Object.keys 获取对象所有的键名
console.log(Object.keys(obj)) // ['name', 'arr1', 'arr2']
// Object.values 获取对象所有的键值
console.log(Object.values(obj)) // ['sky', ['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
// Object.entries() 返回一个给定对象自身可遍历属性 [key,value] 的数组(二维数组)
console.log(Object.entries(obj)) // [['name', 'sky'], ['arr1', ['a', 'b', 'c', 'd']], ['arr2', [1, 2, 3, 4]]]
// 创建 Map
const m = new Map(Object.entries(obj))
console.log(m.get('name')) // 'sky'

// Object.getOwnPropertyDescriptors 返回指定对象所有自身属性的描述对象 
console.log(Object.getOwnPropertyDescriptors(obj))
// 每个对象的属性都有一个描述对象,例:
const obj2 = Object.create(null, {
  name: { // 属性name的描述对象
  	value: 'sky', // 设置值
  	// 属性特性
  	writable: true, // 是否可写
  	configurable: true, // 是否可删除
  	enumerable: true // 是否可枚举
  }
})

ES9

- rest参数与spread扩展运算符

这两个参数在ES6中已经引入,不过在ES6中只针对于数组
ES9中为对象提供了像数组一样的rest参数和扩展运算符

代码例:

// rest参数
function showMessage({id, title, ...info}){
  console.log(id) // 1
  console.log(title) // '标题'
  console.log(info) // {price: 1000, type: '常规'}
}

showMessage({
  id: 1,
  title: '标题',
  price: 1000,
  type: '常规'
})

// spread扩展运算符
const profile1 = {
  name: 'sky',
  gender: '男'
}
const profile2 = {
  age: 18
}
const profile3 = {
  height: '180cm'
}
const profile4 = {
  weight: '70kg'
}
console.log(...profile1) // name: 'sky', gender: '男'
// 利用扩展运算符创建对象属性
const obj = {...profile1, ...profile2, ...profile3, ...profile4}
console.log(obj)
// {name: 'sky', gender: '男', age: 18, height: '180cm', weight: '70kg'}

- 正则扩展

* 命名捕获分组

代码例:

// 声明一个字符串
let str = '<a href="https://www.baidu.com/">百度</a>'

// 普通正则,提取url和其中的标签文本
const reg = /<a href="(.*)">(.*)<\/a>/; // (.*)的部分就是提取处
// 正则命名分组,
const reg2 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/; // (?<{{name}}>.*)  {{name}}处起别名

// 执行
const result = reg.exec(str)
const result2 = reg2.exec(str)

console.log(result[1]) // 'https://www.baidu.com/'
console.log(result[2]) // '百度'

console.log(result2.groups) // {url: 'https://www.baidu.com/', text: '百度'}

* 正则断言

代码例:

// 声明一个字符串
let str = '你好12321321我是文字999000结束了'
// 需求,取出其中的数字999000
// 正向断言
const reg = /\d+(?=结)/;
const result = reg.exec(str)
console.log(result[0]) // '999000'

// 反向断言
const reg2 = /(?<=字)\d+/;
const result2 = reg2.exec(str)
console.log(result2[0]) //  '999000'

* dotAll模式

代码例:

// dot . 元字符,除换行符以外的任意单个字符

// 声明一个字符串
let str = `
<ul>
  <li>
    <div>姓名</div>
    <p>sky</p>
  </li>
  <li>
    <div>性别</div>
    <p>男</p>
  </li>
</ul>`
// 需求,取出其中ul内每个li内div标签和p标签中的内容

// 普通正则,规定其中一个li标签
const reg = /<li>\s+<div>(.*?)<\/div>\s+<p>(.*?)<\/p>/;
// 执行
const result = reg.exec(str)
console.log(result[1]) // '姓名'
console.log(result[2]) // 'sky'

// dotAll模式,末尾加s,「.」可以匹配任意字符,全局匹配再加g
const reg2 = /<li>.*?<div>(.*?)<\/div>.*?<p>(.*?)<\/p>/gs;
let result2
let data = []
while(result2 = reg2.exec(str)){
  console.log(result2) // 依次打印输出2组数据
  data.push({type: result[1], value: result[2]})
}
console.log(data) // [{type: '姓名', value: 'sky'}, {type: '性别', value: '男'}]

ES10

- Object.fromEntries(二维数组或Map转为对象)

可以将一个二维数组或Map转为对象

代码例:

// 转换二维数组
const result = Object.fromEntries([
  ['name', 'sky'],
  ['age', 18]
])
console.log(result) // {name: 'sky', age: 18}

// 转换Map
const m = new Map()
m.set('name', 'sky')
const result2 = Object.fromEntries(m)
console.log(result2) // {name: 'sky'}

- trimStart和trimEnd(去除字符串前面或后面的空格)

代码例:

// 声明一个字符串
let str = '    字符串   '
console.log(str) // '    字符串   '

// ES5中字符串的方法trim
console.log(str.trim()) // '字符串'

// trimStart
console.log(str.trimStart()) // '字符串   '

// trimEnd
console.log(str.trimEnd()) // '    字符串'

- flat(多维数组转为低维数组)

代码例:

// flat 将多维数组转化为低维数组
const arr = [1, 2, 3, 4, [5, 6]]
const arr2 = [1, 2, 3, 4, [5, 6, [7, 8, 9]]]

console.log(arr.flat()) // [1, 2, 3, 4, 5, 6]

// 可传入参数,参数为深度,默认值为1
console.log(arr2.flat(1)) // [1, 2, 3, 4, 5, 6, [7, 8, 9]]
console.log(arr2.flat(2)) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

- flatMap(map函数功能 + 转换低维数组)

代码例:

// flatMap,拥有map函数的功能,但可以将返回结果转化为低维数组(深度只有1)
const arr = [1, 2, 3, 4]
const result = arr.map(item => [item * 10])
const result2 = arr.flatMap(item => [item * 10])

console.log(result) // [[10], [20], [30], [40]]
console.log(result2) // [10, 20, 30, 40]

- Symbol.prototype.description(获取Symbol的描述对象)

代码例:

// 创建Symbol,'sky'为此Symbol的描述对象
let s = Symbol('sky')

// 使用description获取描述对象
console.log(s.description) // 'sky'

ES11

- 类的私有属性

代码例:

// 创建类Person
class Person{
  // 公有属性
  name
  // 私有属性
  #age
  #weight
  // 构造方法
  constructor(name, age, weight){
  	this.name = name
  	this.#age = age
  	this.#weight = weight
  }
  // Person内的函数fn
  fn() {
  	console.log(this.name)
  	console.log(this.#age)
  	console.log(this.#weight)
  }
}

const girl = new Person('小红', 18, '40kg')
console.log(girl) // {name: '小红', #age: 18, #weight: '40kg'}
console.log(girl.name) // '小红'
console.log(girl.#age) // 报错,不能通过类外部的方法获取这个属性

girl.fn() // 执行类Person内部的fn函数,可以正常输出
// '小红'
// 18
// '40kg'

- Promise.allSettled(返回其中所有promise对象的执行结果)

执行allSettled方法需要传入一个数组作为参数,数组内每个元素需要为Promise对象
`
allSettled方法执行后返回一个Promise对象,结果有两个值:

  • 返回状态,此状态不受数组中promise对象的状态影响
  • 返回值,一个包含方法中所有promise对象执行结果及返回值的数组

代码例:

// 声明两个Promise对象
const p1 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
  	resolve('数据1')
  },1000)
})

const p2 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
  	reject('失败了')
  },1000)
})

// 调用 allSettled 方法
const result = Promise.allSettled([p1, p2])
console.log(result)
// [[PromiseState]]: 'fulfilled'
// [[PromiseResult]]: [{status: 'fulfilled', value: '数据1'}, {status: 'rejected', value: '失败了'}]

- String.prototype.matchAll(正则批量匹配)

代码例:

// 声明一个字符串
let str = `
<ul>
  <li>
    <div>姓名</div>
    <p>sky</p>
  </li>
  <li>
    <div>性别</div>
    <p>男</p>
  </li>
</ul>`

// 声明正则
const reg = /<li>.*?<div>(.*?)<\/div>.*?<p>(.*?)<\/p>/gs

// 调用方法
const result = str.matchAll(reg)
// result是个可迭代对象,其中有next方法,因此此处可以使用for...of循环
let data = []
for(let item of result){
  console.log(item)
  data.push({type: item[1], value: item[2]})
}
console.log(data)
// [{type: '姓名', value: 'sky'}, {type: '性别', value: '男'}]

// 使用扩展运算符展开result
const arr = [...result]
console.log(arr)
// [
//   ["<li><div>姓名</div><p>sky</p>", "姓名", "sky"],
//   ["<li><div>性别</div><p>男</p>", "性别", "男"]
// ]

- 可选链操作符 ?.

代码例:

// ?.
function fn(goods){
  // 普通做法,设置商品标题,一层一层判断是否传入
  const goodsTitle = goods && goods.mainInfo && goods.mainInfo.title
  console.log(goodsTitle) // 只要有一层没传入,则报错
  // ?. 可选链操作符
  const goodsTitle2 = goods?.mainInfo?.title
  console.log(goodsTitle2) // 如果最后的title未传入,则为undefined,不会报错
}

fn({
  info: {
  	title: '标题',
  	type: '类型'
  }
})

- 动态import加载

需求:点击按钮,alert内容’hello’

代码例:

<!-- index.html -->
<button id="btn">按钮</button>
<script src="./js/app.js" type="module"></script>

// app.js
// 传统导入方式,无论用不用,都先导入
// import * as j1 from "./hello.js"
const btn = document.getElementById('btn')

btn.onClick = function(){
  // 传统导入方式的使用方式
  // j1.hello()
  
  // 动态import加载,import函数
  // 该函数执行结果是一个promise对象
  import('./hello.js').then(res=>{
    console.log(res) // res里面包含所有hello.js内暴露的对象
    res.hello()
  })
}

// hello.js
export function hello(){
  alert('hello')
}

- 新的数据类型-BigInt 大整数(用于更大的数值运算)

// 大整形
let n = 111n
console.log(n, typeof n) // 521n, 'bigint'

// 函数
let m = 123
console.log(BigInt(m)) // 123n
console.log(BigInt(1.1)) // 报错,BigInt不能用于浮点数

// 大数值运算
let max = Number.MAX_SAFE_INTEGER // js内最大安全整数
console.log(max) // 9007199254740991
console.log(max + 1) // 9007199254740992
console.log(max + 2) // 9007199254740992
// 可以看出,正常运算方式已经无法再往上计算
// 这边可以使用BigInt来进行计算
console.log(BigInt(max)) // 9007199254740991n
console.log(BigInt(max) + BigInt(1)) // 9007199254740992n
console.log(BigInt(max) + BigInt(2)) // 9007199254740993n

- globalThis(全局对象)

无论在什么环境下,始终指向全局对象的一个变量

  • 浏览器环境下,指向window对象
  • node环境(node.js-12)下,指向global对象

- Recorded by Scorpio_sky@2021-01-23

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值