基礎很好?總結了38個ES6-ES12的開發技巧,倒要看看你能拿幾分?🐶

前言

你們好,首先代表一下,標題沒有惡意哈哈。請原諒本菜雞。都是爲了幫助你們,你們能夠把本身認識幾個,得了多少分,發在留言裏哈。一個一分,總分38分面試

你們好,我是林三心,這段時間不少兄弟姐妹都來問我問題,我也看過不少他們的代碼。給個人感受就是,代碼的使用還停留在了ES5的那個階段,不少用新語法就能輕鬆實現的,卻都不怎麼了解,因此我就打算寫一篇文章,總結一下在我工做中用過的很是實用的ES6,ES7,ES8,ES9,ES10,ES11,ES12語法。小程序

首先說明一下:我這裏只是舉了最基礎的例子,可是項目中要怎麼去靈活運用,這個就要各位同窗本身去摸索了。微信小程序

image.png

ES6

一、let 和 const

這兩個的出現,總感受是爲了開發的代碼規範而出現的。咱們要逐漸放棄var,在項目中多用let和const數組

與var的區別:微信

  • var有變量提高,有初始化提高,值可變
  • let有變量提高,沒有初始化提高,值可變
  • const有變量提高,沒有初始化提高,值不可變,但若是是定義對象,則屬性可變

暫時性死區問題說明:其實let和const是有變量提高的,可是沒有初始化提高:markdown

var name = '林三心'

function fn () {
  console.log(name)
  let name = 'sunshin_lin'
}
fn() // Cannot access 'name' before initialization
複製代碼

塊級做用域解決問題:app

for(var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i)
  })
} // 5 5 5 5 5


for(let i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i)
  })
} // 0 1 2 3 4
複製代碼

二、默認參數

開發中你曾遇到過這樣的問題,若是參數不傳進來,你就設置默認參數異步

function fn (name, age) {
  var name = name || '林三心'
  var age = age || 18
  console.log(name, age)
}
fn() // 林三心 18
複製代碼

可是這麼寫確實不優雅,可使用ES6的默認參數async

function fn (name = '林三心', age = 18) {
  console.log(name, age)
}
fn() // 林三心 18
fn('sunshine', 22) // sunshine 22
複製代碼

三、擴展運算符

曾經的我,想要拼接多個數組,我只能這麼作ide

const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]

const arr = arr1.concat(arr2).concat(arr3)
[
  1, 2, 4, 4, 5,
  7, 7, 8, 9
]
複製代碼

如今的我,能夠更優雅地進行拼接

const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]

const arr = [...arr1, ...arr2, ...arr3]
[
  1, 2, 4, 4, 5,
  7, 7, 8, 9
]
複製代碼

四、剩餘參數

你們可能遇到過這種問題,一個函數,傳入參數的個數是不肯定的,這就能夠用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 ]
複製代碼

五、模板字符串

之前的我,拼接字符串只能這麼作

const name = '林三心'
const age = '22'

console.log(name + '今年' + age + '歲啦') // 林三心今年22歲啦
複製代碼

如今我能夠這麼作,會更優雅

const name = '林三心'
const age = '22'

console.log(`${name}今年${age}歲啦`) // 林三心今年22歲啦
複製代碼

六、Object.keys

能夠用來獲取對象的key的集合,進而能夠得到對應key的value

const obj = {
  name: '林三心',
  age: 22,
  gender: '男'
}

const keys = Object.keys(obj)
console.log(keys) // [ 'name', 'age', 'gender' ]
複製代碼

七、箭頭函數

之前咱們使用普通函數

function fn () {}

const fn = function () {}
複製代碼

ES6新加了箭頭函數

const fn = () => {}

// 若是隻有一個參數,能夠省略括號
const fn = name => {}

// 若是函數體裏只有一句return
const fn = name => {
    return 2 * name
}
// 可簡寫爲
const fn = name => 2 * name
// 若是返回的是對象
const fn = name => ({ name: name })
複製代碼

普通函數和箭頭函數的區別:

  • 一、箭頭函數不可做爲構造函數,不能使用new
  • 二、箭頭函數沒有本身的this
  • 三、箭頭函數沒有arguments對象
  • 四、箭頭函數沒有原型對象

八、Array.forEach

ES6新加的數組遍歷方法

const eachArr = [1, 2, 3, 4, 5]

// 三個參數:遍歷項 索引 數組自己
// 配合箭頭函數
eachArr.forEach((item, index, arr) => {
  console.log(item, index, arr)
})
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]
複製代碼

九、Array.map

經常使用於返回一個處理事後的新數組

const mapArr = [1, 2, 3, 4, 5]

// 三個參數:遍歷項 索引 數組自己
// 配合箭頭函數,對每個元素進行翻倍
const mapArr2 = mapArr.map((num, index, arr) => 2 * num)
console.log(mapArr2)
[ 2, 4, 6, 8, 10 ]
複製代碼

十、Array.filter

顧名思義,用來過濾的方法

const filterArr = [1, 2, 3, 4, 5]

// 三個參數:遍歷項 索引 數組自己
// 配合箭頭函數,返回大於3的集合
const filterArr2 = filterArr.filter((num, index, arr) => num > 3)
console.log(filterArr2)
[ 4, 5 ]
複製代碼

十一、Array.some

some,意思就是隻有一個是真,那就返回真

const someArr = [false, true, false, true, false]

// 三個參數:遍歷項 索引 數組自己
// 配合箭頭函數,只要有一個爲true,就返回true,一個都true都沒有,就返回false
const someArr2 = someArr.some((bol, index, arr) => bol)
console.log(someArr2)
true
複製代碼

十二、Array.every

every跟some是相反的,some是隻有一個就行,every是要全部爲真才返回真

const everyArr = [false, true, false, true, false]

// 三個參數:遍歷項 索引 數組自己
// 配合箭頭函數,須要全部爲true,才返回true,不然返回false
const everyArr2 = everyArr.every((bol, index, arr) => bol)
console.log(everyArr2)
複製代碼

1三、Array.reduce

  • 第一個參數callback函數: pre爲上次return的值,next爲數組的本次遍歷的項
  • 第二個參數爲初始值,也是第一個pre

舉兩個例子:

// 計算 1 + 2 + 3 + 4 + 5
const reduceArr = [1, 2, 3, 4, 5]
const sum = reduceArr.reduce((pre, next) => {
  return pre + next
}, 0)
console.log(sum) // 15

// 統計元素出現個數
const nameArr = ['林三心', 'sunshine_lin', '林三心', '林三心', '科比']
const totalObj = nameArr.reduce((pre, next) => {
  if (pre[next]) {
    pre[next]++
  } else {
    pre[next] = 1
  }
  return pre
}, {})
console.log(totalObj) // { '林三心': 3, sunshine_lin: 1, '科比': 1 }

複製代碼

1四、對象屬性同名簡寫

之前同名屬性須要這麼寫

const name = '林三心'
const age = '22'

const obj = {
  name: name,
  age: age
}

console.log(obj) // { name: '林三心', age: '22' }
複製代碼

ES6新增語法,只需這麼寫

const name = '林三心'
const age = '22'

// 屬性同名可簡寫
const obj = {
  name
  age
}

console.log(obj) // { name: '林三心', age: '22' }
複製代碼

1五、Promise

Promise,中文名爲承諾,承諾在哪呢?承諾在,一旦他的狀態改變,就不會再改。這裏就介紹基本使用,若是想要深刻理解如何使用,請看個人另外一篇文章看了就會,手寫Promise原理,最通俗易懂的版本!!!

看看基本使用

  • 成功狀態
function requestData () {
  // 模擬請求
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('林三心')
    }, 1000)
  })
}

requestData().then(res => {
  console.log(res) // 一秒鐘後輸出 '林三心'
}, err => {
  console.log(err)
})
複製代碼
  • 失敗狀態
function requestData () {
  // 模擬請求
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('錯誤啦')
    }, 1000)
  })
}

requestData().then(res => {
  console.log(res)
}, err => {
  console.log(err) // 一秒鐘後輸出 '錯誤啦'
})
複製代碼
  • all方法
    • 接收一個Promise數組,數組中若有非Promise項,則此項當作成功
    • 若是全部Promise都成功,則返回成功結果數組
    • 若是有一個Promise失敗,則返回這個失敗結果
// 若是全都爲成功
function fn(time) {
  return new Promise((resolve, reject) => {
    console.log(88)
    setTimeout(() => {
      resolve(`${time}毫秒後我成功啦!!!`)
    }, time)
  })
}

Promise.all([fn(2000), fn(3000), fn(1000)]).then(res => {
  // 3秒後輸出 [ '2000毫秒後我成功啦!!!', '3000毫秒後我成功啦!!!', '1000毫秒後我成功啦!!!' ]
  console.log(res) 
}, err => {
  console.log(err)
})



// 若是有一個失敗
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒後我成功啦!!!`) : reject(`${time}毫秒後我失敗啦!!!`)
    }, time)
  })
}

Promise.all([fn(2000, true), fn(3000), fn(1000, true)]).then(res => {
  console.log(res)
}, err => {
  console.log(err) // 3秒後輸出 '3000毫秒後我失敗啦!!!'
})
複製代碼
  • race方法
    • 接收一個Promise數組,數組中若有非Promise項,則此項當作成功
    • 哪一個Promise最快獲得結果,就返回那個結果,不管成功失敗
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒後我成功啦!!!`) : reject(`${time}毫秒後我失敗啦!!!`)
    }, time)
  })
}

Promise.race([fn(2000, true), fn(3000), fn(1000)]).then(res => {
  console.log(res)
}, err => {
  console.log(err) // 1秒後輸出
})
複製代碼

1六、class

之前我們使用構造函數生成對象,這麼作

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

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

const kobe = new Person('科比')
kobe.sayName() // 科比
複製代碼

而有了ES6的class能夠這麼作

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

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

const kobe = new Person('科比')
kobe.sayName() // 科比
複製代碼

值得一提的是,class本質也是functionclassfunction語法糖

class Person {}

console.log(typeof Person) // function
複製代碼

除了以上,還須要知道class的如下知識點

靜態屬性和靜態方法,使用static定義的屬性和方法只能class本身用,實例用不了

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

  static age = 22

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

const sunshine_lin = new Person('林三心')
console.log(sunshine_lin.age) // undefined
sunshine_lin.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

複製代碼

1七、解構賦值

之前想提取對象裏的屬性須要這麼作

const obj = {
  name: '林三心',
  age: 22,
  gender: '男'
}

const name = obj.name
const age = obj.age
const gender = obj.gender
console.log(name, age, gender) // 林三心 22 男
複製代碼

ES6新增瞭解構賦值的語法

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
複製代碼

1八、find 和 findIndex

  • find:找到返回被找元素,找不到返回undefined
  • findIndex:找到返回被找元素索引,找不到返回-1
const findArr = [
  { name: '科比', no: '24' },
  { name: '羅斯', no: '1' },
  { name: '利拉德', no: '0' }
]

const kobe = findArr.find(({ name }) => name === '科比')
const kobeIndex = findArr.findIndex(({ name }) => name === '科比')
console.log(kobe) // { name: '科比', no: '24' }
console.log(kobeIndex) // 0
複製代碼

1九、for of 和 for in

  • for in :遍歷方法,可遍歷對象和數組
  • for of :遍歷方法,只能遍歷數組,不能遍歷對象

先看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
複製代碼

20、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的不重複性中,要注意引用數據類型和NaN

// 兩個對象都是不用的指針,因此無法去重
const set1 = new Set([1, {name: '林三心'}, 2, {name: '林三心'}])
console.log(set1) // Set(4) { 1, { name: '林三心' }, 2, { name: '林三心' } }


// 若是是兩個對象是同一指針,則能去重
const obj = {name: '林三心'}
const set2 = new Set([1, obj, 2, obj])
console.log(set2) // Set(3) { 1, { name: '林三心' }, 2 }

我們都知道 NaN !== NaNNaN是自身不等於自身的,可是在Set中他仍是會被去重
const set = new Set([1, NaN, 1, NaN])
console.log(set) // Set(2) { 1, NaN }
複製代碼

利用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, '哈哈' => '嘻嘻嘻' }
複製代碼

ES7

2一、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 = Math.pow(3, 2) // 9
複製代碼

ES7提供了求冪運算符:**

const num = 3 ** 2 // 9
複製代碼

ES8

2三、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', '男' ] ]
複製代碼

2五、async/await

這個是很經常使用的語法了,個人理解就是:以同步方式執行異步操做

咱們平時可能會遇到這種場景,接口一,請求到數據一,而數據一被當作請求二的參數去請求數據二,咱們會用Promise這麼作

function fn() {
  // 模擬第一次請求
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(5)
    }, 1000)
  }).then(res => {
    // 模擬第二次請求
    new Promise((resolve, reject) => {
      setTimeout(() => {
        // 拿第一次請求的數據去乘10,當作第二次請求的數據
        resolve(res * 10)
      }, 2000)
    }).then(sres => {
      console.log(sres)
    })

  })
}
fn() // 1 + 2 = 3 3秒後輸出 50
複製代碼

這樣的嵌套是不美觀的,若是有不少個接口,那就會嵌套不少層,此時咱們可使用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()
複製代碼

ES9

2六、for await of

咱們來看如下場景哈

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

fn(3000).then(res => console.log(res))
fn(1000).then(res => console.log(res))
fn(2000).then(res => console.log(res))

結果是

1000毫秒後我成功啦!!!
2000毫秒後我成功啦!!!
3000毫秒後我成功啦!!!
複製代碼

可是我想要這個結果

3000毫秒後我成功啦!!!
1000毫秒後我成功啦!!!
2000毫秒後我成功啦!!!
複製代碼

第一時間咱們確定想到的是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(3000), fn(1000), fn(1000), fn(2000), fn(500)]
  for await (let x of arr) {
    console.log(x)
  }
}

asyncFn()
3000毫秒後我成功啦!!!
1000毫秒後我成功啦!!!
1000毫秒後我成功啦!!!
2000毫秒後我成功啦!!!
500毫秒後我成功啦!!!
複製代碼

2七、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') })
複製代碼

ES10

2八、Array.flat

有一個二維數組,我想讓他變成一維數組:

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

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

還能夠傳參數,參數爲降維的次數

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

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

若是傳的是一個無限大的數字,那麼就實現了多維數組(不管幾維)降爲一維數組

const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]]

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

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(" ")));
// [ '科比', '詹姆斯', '安東尼', '利拉德', '羅斯', '麥科勒姆' ]
複製代碼

30、BigInt

BigInt是ES10新加的一種JavaScript數據類型,用來表示表示大於 2^53 - 1 的整數,2^53 - 1是ES10以前,JavaScript所能表示最大的數字

const theBiggestInt = 9007199254740991n;

const alsoHuge = BigInt(9007199254740991);
// 9007199254740991n

const hugeString = BigInt("9007199254740991");
// 9007199254740991n

const hugeHex = BigInt("0x1fffffffffffff");
// 9007199254740991n

const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
// 9007199254740991n
複製代碼

哦對了,既然是JavaScript新的數據類型,那他的typeof是啥?

const bigNum = BigInt(1728371927189372189739217)
console.log(typeof bigNum) // bigint
複製代碼

因此之後面試官問你JavaScript有多少種數據類型,別傻傻答6種了,要答8種,把ES6的Symbol和ES10的BigInt也加上去

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: '男' }
複製代碼

3二、String.trimStart && String.trimEnd

我們都知道JavaScript有個trim方法,能夠清除字符串首尾的空格

const str = ' 林三心 '
console.log(str.trim()) // '林三心'
複製代碼

trimStart和trimEnd用來單獨去除字符串的首和尾的空格

const str = ' 林三心 '

// 去除首部空格
console.log(str.trimStart()) // '林三心 '
// 去除尾部空格
console.log(str.trimStart()) // ' 林三心'
複製代碼

ES11

3三、Promise.allSettled

ES11新增的Promise的方法

  • 接收一個Promise數組,數組中若有非Promise項,則此項當作成功
  • 把每個Promise的結果,集合成數組,返回
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒後我成功啦!!!`) : reject(`${time}毫秒後我失敗啦!!!`)
    }, time)
  })
}

Promise.allSettled([fn(2000, true), fn(3000), fn(1000)]).then(res => {
  console.log(res)
  // 3秒後輸出 
  [
  { status: 'fulfilled', value: '2000毫秒後我成功啦!!!' },
  { status: 'rejected', reason: '3000毫秒後我失敗啦!!!' },
  { status: 'rejected', reason: '1000毫秒後我失敗啦!!!' }
]
})

複製代碼

3四、?. 和 ??

  • 先說說?.,中文名爲可選鏈

好比咱們須要一個變量,是數組且有長度,才作某些操做

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 ?? '林三心' // 林三心
複製代碼

ES12

3五、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
})
複製代碼

3六、數字分隔符

數字分隔符可讓你在定義長數字時,更加地一目瞭然

const num = 1000000000

// 使用數字分隔符
const num = 1_000_000_000
複製代碼

3七、||= 和 &&=

或等於(||=)   a ||= b 等同於 a || (a = b);

且等於(&&=)   a &&= b 等同於 a && (a = b);
複製代碼

不知道是ES幾

3八、對象動態屬性

咱們常常碰到這樣的問題,不管是在微信小程序仍是React中,咱們須要根據某個條件去修改某個數據

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

我也不知道這個新特性叫啥,我就本身取名叫屬性動態屬性哈哈哈

this.setData({
  [`${type}Name`]: name
})
複製代碼

結語

不少的方法我只講最基礎的,具體在開發中怎樣去靈活運用,同窗們能夠本身去摸索哈,這個很難教,只能靠理論+實踐+積累

若是你以爲本文章對你有一點點幫助的話,請點個贊哈哈。

學習羣請點這裏,一塊兒學習,一塊兒摸魚!!!

image.png

相關文章
相關標籤/搜索