2018都過一半了,還沒來得及看ES8?

過了一個五一長期以後,發現2018年都過去一半了,尷尬的計劃卻趕不上時光的變化。javascript

1、函數參數容許尾後逗號

對於這個特性的更改,個人感觸仍是很深的:每當刪除或者添加函數末尾參數時,你不得不在前一個參數的後面刪除或者添加逗號。這種操做很逆天。java

翻翻文檔,其實早在ES5時代已經支持對象尾後逗號的書寫,可是在JSON中是不容許尾後逗號的。web

Tip: JSON.stringify()會自動去掉對象的尾後逗號。app

2、String的padStart和padEnd

'咦嘻嘻'.padStart(10, '-') // -------咦嘻嘻
  '咦嘻嘻'.padEnd(10, '-')   // 咦嘻嘻-------
複製代碼

Tip: 當長度小於字符串自己長度則返回字符串自己dom

看到這個方法,咱們不難會想起在此以前會經過什麼方法去解決此類的問題。ecmascript

('----------' + '咦嘻嘻').slice(-10) // -------咦嘻嘻
複製代碼

在ES6以前咱們能夠經過slice加上固定的padString實現需求,顯然缺點也很明顯:padString的長度不夠靈活。異步

('-'.repeat(10) + '咦嘻嘻').slice(-10) // -------咦嘻嘻
複製代碼

進入ES6以後,咱們能夠經過repeat結合slice實現,固然遠沒有padEnd來得方便。async

繼表情包大戰以後,聊天發表情,評論發表情幾乎是隨處可見。而咱們在字符串的處理中就須要注意emoji表情:函數

const s = '😀'
  s.length // 2
複製代碼

因而可知,採用emoji做爲padString時可能出現截斷狀況。fetch

console.log('咦嘻嘻'.padStart(10, s)) // 😀😀😀�咦嘻嘻
複製代碼

雖然這是讓人頭疼的地方,可是emoji也有一些趣事

const s1 = '👨‍👩‍👦'
  [...s1] // [ '👨', '‍', '👩', '‍', '👦' ]
複製代碼

3、Object的values和entries

這兩個方法與ES5中的Object.keys()是相似的:

const fruits = {
    apple: 2,
    orange: 10
  }
  Object.keys(fruits) // [ 'apple', 'orange' ]
  Object.values(fruits) // [ 2, 10 ]
  Object.entries(fruits) // [ [ 'apple', 2 ], [ 'orange', 10 ] ]
複製代碼

它們都是獲取枚舉屬性而且不讀取原型上的屬性。

其實到這裏,你們也會想起另外一種遍歷對象的方法:

for (var key in fruits) {
    if (fruits.hasOwnProperty(key)) {
      console.log(key)
    }
  }
複製代碼

沒有對比就沒有傷害,for-in就會讀取原型上的屬性,爲了避免出現意想不到的錯誤,一般咱們會使用hasOwnProperty來過濾原型上的屬性。

總結上面這四種遍歷對象的方法,它們一個共同點就是隻獲取枚舉屬性,那麼問題來了,若是想獲取非枚舉屬性怎麼辦呢?

Object.defineProperty(fruits, 'peach', {
    value: 18,
    enumerable: false
  })

  Object.getOwnPropertyNames(fruits).filter(item => !fruits.propertyIsEnumerable(item)) // [ 'peach' ]
複製代碼

這裏細心的同窗可能還會發現一個問題:在ES6中爲了解決字符串做爲屬性名帶來的惟一性問題,能夠採用Symbol做爲屬性名使用,那麼Symbol屬性名能書獲取到嗎?

Object.defineProperty(fruits, Symbol('banana'), {
    value: 20
  })
  Object.getOwnPropertySymbols(fruits) // [ Symbol(banana) ]
複製代碼

這裏,忽然想起了香鍋的騷話,固然咱們要的是枚舉屬性、非枚舉屬性以及Symbol屬性:

Reflect.ownKeys(fruits) // [ 'apple', 'orange', 'peach', Symbol(banana) ]
複製代碼

4、Object上的另外一個方法 getOwnPropertyDescriptors

對於這個方法,你們應該不太陌生,由於在ES5中咱們定義對象時會採用:

const obj = {}

  Object.defineProperty(obj, 'name', {
    value: 'xiaoyun',
    enumerable: true,
    writable: true,
    configurable: true
  })
複製代碼

而且會使用getOwnPropertyDescriptor獲取它的描述器屬性:

Object.getOwnPropertyDescriptor(obj, 'name')
複製代碼

Tip: 採用對象字面聲明的屬性的描述器屬性默認爲true,採用defineProperty聲明的屬性的描述器屬性的默認值爲false

因此看到這個方法名,天然就知道它是幹什麼的:

Object.getOwnPropertyDescriptors(obj)
複製代碼

固然,它的出現不只僅是由於這個問題。在ES6中新增的拷貝方法assign,它並不能處理描述器屬性,因此涉及到描述器屬性的對象,不能經過assign來拷貝,因此有了getOwnPropertyDescriptors方法以後,咱們能夠這樣處理設置描述器屬性的對象:

Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj))
複製代碼

5、async/await

對於這個新特性的出現,真是的是讓人眼前一亮。

Tip:實際上async很早就被討論了,以致於不少人認爲它是ES6或者ES7標準,實際上它在2017才被正式列入標準,應該屬於ES8標準。

對於async/await,你必需要知道:

  • async是用來聲明一個異步函數,而且它默認返回一個Promise對象;
  • await操做符必須在async中使用;
  • await操做符後面必定是Promise對象,若是是普通對象,它會默認用Promise.resolve()包裹。
function fetchNumber () {
    return new Promise((resolve, reject) => {
      setTimeout(_ => {
        const num = Number.parseInt(Math.random() * 10)
        if (num >= 5) {
          resolve(num)
        } else {
          reject(new Error(`${num} is smaller than 5`))
        }
      }, 1000)
    })
  }

  async function task () {
    try {
      const num = await fetchNumber()
      return num
    } catch (e) {
      return Promise.reject(e.message)
    }
  }

  task().then(console.log).catch(console.log)
複製代碼

在使用async時,千萬不要由於它同步的寫法而陷入誤區,具體咱們須要分析咱們的異步,例如:咱們調用多個fetchNumber時,它們之間並無依賴關係,那麼咱們應該這樣寫:

const [num1, num2] = await Promise.all([fetchNumber(), fetchNumber()])
複製代碼

固然若是這兩個方法有相互依賴的關係,那麼就須要:

const num1 = await fetchNumber()
  const num2 = await fetchNumber()
複製代碼

對於async的異常處理,基本上仍是採用try/catch的方式,固然也有對try/catch詬病的傳送門

參考文章


    喜歡本文的小夥伴們,歡迎關注個人訂閱號超愛敲代碼,查看更多內容.

相關文章
相關標籤/搜索