es7 es8 es9 es10 新增相关属性

186 阅读2分钟

es7 es8 es9 es10 新增相关属性

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

const includeArr = [12 , 3'林三心''科比']
const isKobe = includeArr.includes('科比')
console.log(isKobe) // [true](url)

和indexOf 很像

const arr = [12, NaN]
console.log(arr.indexOf(NaN)) // -1  indexOf找不到NaN
console.log(arr.includes(NaN)) // true includes能找到NaN

2.求幂运算

以前是这么写的

const num = Math.pow(32// 9

现在是

const num = 3**2 // 9

3.Object.values

Object.keys

Object.enteries

可以用来获取对象的键值对集合

let obj={name:'张三',age:100}
cosnole.log(Object.enteries(obj))
// [['name','张三']['age',100]]

4.for await of

我们来看以下场景哈

function fn(tm){
return new Promise((reslove,reject)=>{
    setTimeOut(()=>{
        reslove(console.log(`${tm}毫秒后我成功啦`))
    },
    tm)
})
}
fn(300)
fn(200)
fn(100)

期望打印结果:
300毫秒后我成功啦
200毫秒后我成功啦
100毫秒后我成功啦

然而实际打印结果:
300毫秒后我成功啦
200毫秒后我成功啦
100毫秒后我成功啦

第一时间我们肯定想到的是async/await

function fn (time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time}毫秒后我成功啦!!!`)
    }, time)
  })
}

async function asyncFn () {
  // 排队
  const data1 = await fn(3000)
  console.log(data1) // 3秒后 3000毫秒后我成功啦!!!
  const data2 = await fn(1000)
  console.log(data2) // 再过1秒 1000毫秒后我成功啦!!!
  const data3 = await fn(2000)
  console.log(data3) // 再过2秒 2000毫秒后我成功啦!!!
}

但是上面代码也是有缺点的,如果有几十个,那不是得写几十个await,有没有一种方法可以通过循环来输出呢?

function fn (time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time}毫秒后我成功啦!!!`)
    }, time)
  })
}

async function asyncFn () {
  const arr = [fn(300), fn(200), fn(100), fn(50)]
  for await (let x of arr) {
    console.log(x)
  }
}

asyncFn()
300毫秒后我成功啦!!!
200毫秒后我成功啦!!!
100毫秒后我成功啦!!!
50毫秒后我成功啦!!!

5、Array.flat

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

const arr = [123, [456]]

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

还可以传参数,参数为降维的次数

const arr = [123, [456, [789]]]

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

如果传的是一个无限大的数字,那么就实现了多维数组(无论几维)降为一维数组

const arr = [123, [456, [789, [101112]]]]

console.log(arr.flat(Infinity))
[
   1,  2, 3, 4,  5,
   6,  7, 8, 9, 10,
   11, 12
]

6、Array.flatMap

现在给你一个需求

let arr = ["科比 詹姆斯 安东尼""利拉德 罗斯 麦科勒姆"];

将上面数组转为

'科比''詹姆斯''安东尼''利拉德''罗斯''麦科勒姆' ]

第一时间想到map + flat

console.log(arr.map(x => x.split(" ")).flat());
// [ '科比''詹姆斯''安东尼''利拉德''罗斯''麦科勒姆' ]

flatMap就是flat + map,一个方法顶两个

console.log(arr.flatMap(x => x.split(" ")));
// [ '科比''詹姆斯''安东尼''利拉德''罗斯''麦科勒姆' ]

9、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: '男' }

10、?. 和 ??

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

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

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 fn = null
// do something
const res = fn && fn()

// 可选链
const fn = null
// do something
const res = fn?.()
  • 再说说??,中文名为空位合并运算符 请看以下代码,咱们使用||运算符,只要左边是假值,就会返回右边的数据
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 ?? '林三心' // 林三

11、对象计算属性

我们经常碰到这样的问题,无论是在微信小程序还是React中,我们需要根据某个条件去修改某个数据

if (type === 'boy') {
  this.setData({
    boyName: name
  })
} else if (type === 'girl') {
  this.setData({
    girlName: name
  })
}

我也不知道这个新特性叫啥,我就自己取名叫属性动态属性哈哈哈

this.setData({
  [`${type}Name`]: name
})

补充

12、Symbol

应用场景1:使用Symbol来作为对象属性名

平常我们对象的属性都是字符串

const obj = {
  name: 'Sunshine_Lin',
  age: 23
}
console.log(obj['name']) // 'Sunshine_Lin'
console.log(obj['age']) // 23

其实也可以用Symbol来当做属性名

const gender = Symbol('gender')
const obj = {
  name'Sunshine_Lin',
  age23,
  [gender]: '男'
}
console.log(obj['name']) // 'Sunshine_Lin'
console.log(obj['age']) // 23
console.log(obj[gender]) // 男

但是Symbol作为属性的属性不会被枚举出来,这也是JSON.stringfy(obj)时,Symbol属性会被排除在外的原因

console.log(Object.keys(obj)) // [ 'name', 'age' ]
for(const key in obj) {
  console.log(key) // name age
}
console.log(JSON.stringify(obj)) // {"name":"Sunshine_Lin","age":23}

其实想获取Symbol属性也不是没办法。

// 方法一
console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(gender) ]
// 方法二
console.log(Reflect.ownKeys(obj)) // [ 'name', 'age', Symbol(gender) ]

应用场景2:使用Symbol来替代常量

有以下场景

// 赋值
const one = 'oneXin'
const two = 'twoXin'

function fun(key) {
  switch (key) {
    case one:
        return 'one'
      break;
    case two:
        return 'two'
      break;
  }
}

如果变量少的话还好,但是变量多的时候,赋值命名很烦,可以利用Symbol的唯一性

const one = Symbol()
const two = Symbol()

应用场景3:使用Symbol定义类的私有属性

以下例子,PASSWORD属性无法在实例里获取到

class Login {
  constructor(username, password) {
    const PASSWORD = Symbol()
    this.username = username
    this[PASSWORD] = password
  }
  checkPassword(pwd) { return this[PASSWORD] === pwd }
}

const login = new Login('123456''hahah')

console.log(login.PASSWORD// 报错
console.log(login[PASSWORD]) // 报错
console.log(login[PASSWORD]) // 报错

mp.weixin.qq.com/s/knmV9Y6Fk…