日常工作使用的 ES6-ES12

94 阅读7分钟

大家好,我是鹿萌萌,总结一下在我工作中用过的非常实用的ES6,ES7,ES8,ES9,ES10,ES11,ES12语法。 如果觉得还不错,那就给个一键3连吧

首先说明一下:我这里只是举了最基础的例子,但是项目中要怎么去灵活运用,这个就要各位同学自己去探索了。

ES12

1、Promise.any

E12新增的Promise的方法

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
  • 如果有一个Promise成功,则返回这个成功结果
  • 如果所有Promise都失败,则报错
// 当有成功的时候,返回最快那个成功
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒后我成功啦!`) : reject(`${time}毫秒后我失败啦!`)
    }, time)
  })
}

Promise.any([fn(2000, true), fn(3000), fn(1000, true)]).then(res => {
  console.log(res) // 1秒后 输出  1000毫秒后我成功啦
}, err => {
  console.log(err)
})

// 当全都失败时
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒后我成功啦!`) : reject(`${time}毫秒后我失败啦!`)
    }, time)
  })
}

Promise.any([fn(2000), fn(3000), fn(1000)]).then(res => {
  console.log(res)
}, err => {
  console.log(err) // 3秒后 报错 all Error
})

2、数字分隔符

数字分隔符可以让你在定义长数字时,更加地一目了然

const num = 1000000000

// 使用数字分隔符
const num = 1_000_000_000

ES11

1、?. 和 ??

  • 先说说?.,中文名为可选链

比如我们需要一个变量,是数组且有长度,才做某些操作

const list = null
// do something
if (list && list.length) {
  // do something
}

// 使用可选链
const list = null
// do something
if (list?.length) {
  // do something
}

比如有一个对象,我要取一个可能不存在的值,甚至我们都不确定obj是否存在

const obj = {
  cat: {
    name: '哈哈'
  }
}
const dog = obj && obj.dog && obj.dog.name // undefined

// 可选链
const obj = {
  cat: {
    name: '哈哈'
  }
}
const dog = obj?.dog?.name // undefined

比如有一个数组,我不确定它存不存在,存在的话就取索引为1的值

const arr = null
// do something
const item = arr && arr[1]

// 可选链
const arr = null
// do something
const item = arr?.[1]
  • 再来说说??,中文名为空位合并运算符 请看以下代码,咱们使用||运算符,只要左边是假值,就会返回右边的数据
const a = 0 || '鹿萌萌' // 鹿萌萌
const b = '' || '鹿萌萌' // 鹿萌萌
const c = false || '鹿萌萌' // 鹿萌萌
const d = undefined || '鹿萌萌' // 鹿萌萌
const e = null || '鹿萌萌' // 鹿萌萌

??||最大的区别是,在??这,只有undefined和null才算假值

const a = 0 ?? '鹿萌萌' // 0 
const b = '' ?? '鹿萌萌' // '' 
const c = false ?? '鹿萌萌' // false 
const d = undefined ?? '鹿萌萌' // 鹿萌萌
const e = null ?? '鹿萌萌' // 鹿萌萌

ES10

1、Array.flat

有一个二维数组,我想让它变成一维数组:

const arr = [1, 2, 3, [4, 5, 6]]

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

2、Array.flatMap

现在有一个需求
let arr = ["萝卜 白菜 胡萝卜", "香蕉 苹果 大鸭梨"];
将上面数组转为
[ '萝卜', '白菜', '胡萝卜', '香蕉', '苹果', '大鸭梨' ];
第一时间想到`map + flat`
console.log(arr.map(x => x.split(" ")).flat());
// ['萝卜', '白菜', '胡萝卜', '香蕉', '苹果', '大鸭梨']
`flatMap`就是`flat + map`,一个方法顶两个
console.log(arr.flatMap(x => x.split(" ")));
// ['萝卜', '白菜', '胡萝卜', '香蕉', '苹果', '大鸭梨']

3、Object.fromEntries

ES8的Object.entries是把对象转成键值对数组,而Object.fromEntries则相反,是把键值对数组转为对象

const arr = [
  ['name', '鹿萌萌'],
  ['age', 22],
  ['gender', '女']
]

console.log(Object.fromEntries(arr)) // { name: '鹿萌萌', age: 22, gender: '女' }

还有一个用处,就是把Map转为对象

const map = new Map()
map.set('name', '鹿萌萌')
map.set('age', 22)
map.set('gender', '女')

console.log(map) // Map(3) { 'name' => '鹿萌萌', 'age' => 22, 'gender' => '女' }

const obj = Object.fromEntries(map)
console.log(obj) // { name: '鹿萌萌', age: 22, gender: '女' }

ES9

1、Promise.finally

新增的Promise方法,无论失败或者成功状态,都会执行这个函数

// cheng
new Promise((resolve, reject) => {
  resolve('成功喽')
}).then(
  res => { console.log(res) },
  err => { console.log(err) }
).finally(() => { console.log('我是finally') })

new Promise((resolve, reject) => {
  reject('失败喽')
}).then(
  res => { console.log(res) },
  err => { console.log(err) }
).finally(() => { console.log('我是finally') })

ES8

1、Object.values

可以用来获取对象的value的集合

const obj = {
  name: '鹿萌萌',
  age: 22,
  gender: '女'
}

const values = Object.values(obj)
console.log(values) // [ '鹿萌萌', 22, '女' ]

2、Object.entries

const obj = {
  name: '鹿萌萌',
  age: 22,
  gender: '女'
}

const entries = Object.entries(obj)
console.log(entries) 
// [ [ 'name', '鹿萌萌' ], [ 'age', 22 ], [ 'gender', '女' ] ]

3、async/await

  • await只能在async函数里使用
  • await后面最好接Promise,如果后面接的是普通函数则会直接执行
  • async函数返回的是一个Promise
function fn1 () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(5)
    }, 1000)
  })
}

function fn2 (data) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(data * 10)
    }, 2000)
  })
}

async function req () {
  // 同步方式执行异步,像排队一样
  const data1 = await fn1() // 等待1秒后返回数据再往下执行
  const data2 = await fn2(data1) // 拿data1去请求2秒后,往下走
  console.log(data2) // 总共3秒后 输出 50
}
req()

ES7

1、includes

传入元素,如果数组中能找到此元素,则返回true,否则返回false

const includeArr = [1, 2 , 3, '鹿萌萌']

const isKobe = includeArr.includes('鹿萌萌')
console.log(isKobe) // true

跟indexOf很像,但还是有区别的

const arr = [1, 2, NaN]

console.log(arr.indexOf(NaN)) // -1  indexOf找不到NaN
console.log(arr.includes(NaN)) // true includes能找到NaN

2、求幂运算符

const num = 3 ** 2 // 9

ES6

1、for of 和 for in

  • for in :遍历方法,可遍历对象和数组
  • for of :遍历方法,只能遍历数组,不能遍历非iterable对象 先看for in:
const obj = { name: '鹿萌萌', age: 22, gender: '女' }
const arr = [1, 2, 3, 4, 5]

for(let key in obj) {
  console.log(key)
}
name
age
gender

for(let index in arr) {
  console.log(index)
}
0 1 2 3 4
  • for of
for(let item of arr) {
  console.log(item)
}
1 2 3 4 5

2、Set 和 Map

  • Set 先说说Set的基本用法
// 可不传数组
const set1 = new Set()
set1.add(1)
set1.add(2)
console.log(set1) // Set(2) { 1, 2 }

// 也可传数组
const set2 = new Set([1, 2, 3])
// 增加元素 使用 add
set2.add(4)
set2.add('鹿萌萌')
console.log(set2) // Set(5) { 1, 2, 3, 4, '鹿萌萌' }
// 是否含有某个元素 使用 has
console.log(set2.has(2)) // true
// 查看长度 使用 size
console.log(set2.size) // 5
// 删除元素 使用 delete
set2.delete(2)
console.log(set2) // Set(4) { 1, 3, 4, '鹿萌萌' }

再来说说Set的不重复性

// 增加一个已有元素,则增加无效,会被自动去重
const set1 = new Set([1])
set1.add(1)
console.log(set1) // Set(1) { 1 }

// 传入的数组中有重复项,会自动去重
const set2 = new Set([1, 2, '鹿萌萌', 3, 3, '鹿萌萌'])
console.log(set2) // Set(4) { 1, 2, '鹿萌萌', 3 }

利用Set的不重复性,可以实现数组去重
const arr = [1, 2, 3, 4, 4, 5, 5, 66, 9, 1]
// Set可利用扩展运算符转为数组哦
const quchongArr = [...new Set(arr)]
console.log(quchongArr) // [1,  2, 3, 4, 5, 66, 9]
  • Map Map对比object最大的好处就是,key不受类型限制
// 定义map
const map1 = new Map()
// 新增键值对 使用 set(key, value)
map1.set(true, 1)
map1.set(1, 2)
map1.set('哈哈', '嘻嘻嘻')
console.log(map1) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }
// 判断map是否含有某个key 使用 has(key)
console.log(map1.has('哈哈')) // true
// 获取map中某个key对应的value 使用 get(key)
console.log(map1.get(true)) // 2
// 删除map中某个键值对 使用 delete(key)
map1.delete('哈哈')
console.log(map1) // Map(2) { true => 1, 1 => 2 }

// 定义map,也可传入键值对数组集合
const map2 = new Map([[true, 1], [1, 2], ['哈哈', '嘻嘻嘻']])
console.log(map2) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }
// 使用Object.fromEntries将map类型转为对象类型
const obj = Object.fromEntries(map2) console.log(obj) // {1: 2, true: 1, 哈哈: '嘻嘻嘻'}

3、解构赋值

const obj = {
  name: '鹿萌萌',
  age: 22,
  gender: '女',
  doing: {
    morning: '睡觉',
    afternoon: '睡觉',
    evening: 'sleep'
  }
}

const { name, age, gender } = obj
console.log(name, age, gender) // 鹿萌萌 22 女

// 解构重名
const { name: myname } = obj
console.log(myname) // 林三心

// 嵌套解构
const { doing: { evening } } = obj
console.log(evening) // sleep

也可以进行数组的解构

const arr = [1, 2, 3]

const [a, b, c] = arr
console.log(a, b, c) // 1 2 3

// 默认赋值
const [a, b, c, d = 5] = arr
console.log(a, b, c, d) // 1 2 3 5

// 乱序解构
const { 1: a, 0: b, 2: c } = arr
console.log(a, b, c) // 2 1 3

4、class

ES6之前使用构造函数生成对象,这么做

function Person(name) {
  this.name = name
}

Person.prototype.sayName = function () {
  console.log(this.name)
}

const meng = new Person('鹿萌萌')
meng.sayName() // 鹿萌萌

而有了ES6的class可以这么做

class Person {
  constructor(name) {
    // 构造器
    this.name = name
  }

  sayName() {
    console.log(this.name)
  }
}

const meng = new Person('鹿萌萌')
meng.sayName() // 鹿萌萌

class本质也是functionclassfunction语法糖

class Person {}

console.log(typeof Person) // function

静态属性和静态方法,使用static定义的属性和方法只能class自己用,实例用不了

class Person {
  constructor(name) {
    this.name = name
  }

  static age = 22

  static fn() {
    console.log('哈哈')
  }
}
console.log(Person.age) // 22
Person.fn() // 哈哈

const meng = new Person('鹿萌萌')
console.log(meng.age) // undefined
meng.fn() // fn is not a function

extend继承

class Animal {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
}

class Cat extends Animal {
  say() {
    console.log(this.name, this.age)
  }
}

const cat = new Cat('ketty', 5) // 继承了Animal的构造器
cat.say() // ketty 5

5、剩余参数

大家可能遇到过这种问题,一个函数,传入参数的个数是不确定的,这就可以用ES6的剩余参数

function fn (name, ...params) {
  console.log(name)
  console.log(params)
}
fn ('鹿萌萌', 1, 2) // 鹿萌萌 [ 1, 2 ]
fn ('鹿萌萌', 1, 2, 3, 4, 5) // 鹿萌萌 [ 1, 2, 3, 4, 5 ]