前端培訓-中級階段(29)- ES6語法(2019-12-12期)

前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。javascript

前言BB

放開我,我又要吐槽了。看到這個題目的時候,我十分的頭禿。
那麼我爲何頭禿呢?html

  1. ECMAScript 6(ES2015) 作了大量的更新。
    那麼多的更新我那說的完ECMAScript 6 入門 - 阮一峯,這裏發一下學習連接,只能說大佬牛逼。
  2. 2015 年 6 月正式發佈。
    如今來講都四年過去了。其實大多數人都掌握了。
  3. 其實還有一個誤區不是ES5的都歸ES6
    其實想一想挺逗的。爲何會有這樣一個誤區?ES2015出來的時候瀏覽器廠商支持就不同,ES2016出來以後支持仍是不同,ES201七、ES201八、ES2019 都是這樣。這就出現了一個問題,發布是發佈了,可是啥時候支持就不必定了
    這裏放出來我前兩天才看的文章,他們的更新速度是真的恐怖。前端

    1. 從 JavaScript、ES六、ES7 到 ES10,你學到哪兒了? - 瘋狂的技術宅
    2. 盤點ES七、ES八、ES九、ES10新特性 - 浪裏行舟

提案流程

從提案到正式標準,須要經歷五個階段。每一個階段的變更都須要由 TC39 委員會批准。vue

  1. Stage 0 - Strawman(展現階段)
    有人提出的想法(任何人均可以向 TC39 委員會提案,要求修改語言標準)
  2. Stage 1 - Proposal(徵求意見階段)
    想法公佈,進行審查與討論
  3. Stage 2 - Draft(草案階段)
    想法完善,初始規範
  4. Stage 3 - Candidate(候選人階段)
    肯定要作,完成規範並在瀏覽器上初步實現。
  5. Stage 4 - Finished(定案階段)
    到達這裏基本就能夠在瀏覽器用了。將添加到下一個年度版本發佈中。IE什麼的你就不要和我提了

當前的全部提案,能夠在 TC39 的官方網站查看java

Babel 是什麼?

Babel 是一個 JavaScript 編譯器。將 ECMAScript 2015+ 版本的代碼轉換爲向後兼容的 JavaScript 語法,以便可以運行在當前和舊版本的瀏覽器或其餘環境中。下面列出的是 Babel 能作的事情:node

  • 語法轉換
  • 經過 Polyfill 方式在目標環境中添加缺失的特性 (經過@babel/polyfill模塊)
  • 源碼轉換 (codemods)

配置文件 .babelrc

{
  // presets字段設定轉碼規則
  "presets": ["es2015", "react", "stage-2"],
  // 插件
  "plugins": ["transform-decorators-legacy", "transform-class-properties"]
}

執行順序

  • plugins 在 Presets 前運行。
  • plugins 順序是從前日後(transform-decorators-legacy、ransform-class-properties)。
  • Preset 順序是從後往前(stage-二、react、es2015)。

官方預設

官方已經針對經常使用環境編寫了一些 preset:react

polyfill

Babel 默認只轉換新的 JavaScript 句法(syntax),而不轉換新的 API,好比 IteratorGeneratorSetMapProxyReflectSymbolPromise 等全局對象,以及一些定義在全局對象上的方法(好比Object.assignArray.includes)都不會轉碼。ios

因此咱們還須要使用 babel-polyfillgit

ES6

後面的東西其實看不看無所謂,想要學習呢,仍是看阮一峯大佬的好了。
我這裏說一下我認爲ES6更新了一些什麼東西。es6

  1. 標準化(國際化、unicode、規範化、健壯性、跨平臺)
  2. 功能方法(以前用奇奇怪怪的方法實現的功能,此次官方給你了)
  3. 便捷(腳本語言玩的就是騷氣)

let、const、塊級做用域、暫時性死區

在以前沒有塊級做用域的概念(try{}catch(e){} 能夠模擬,性能呵呵呵呵)。此次加入了塊級做用域的概念,let 變量,const 常量。

// 輸出什麼?
for(var i = 0; i<4;i++){};
i // 4
// 輸出什麼?
for(let i1 = 0; i1<4;i1++){};
i1 //Uncaught ReferenceError: i1 is not defined

變量提高與暫時性死區

你們都知道面試的時候,喜歡搞一些花裏胡哨的鬼東西。
提高是說,var 會被提高到最前面執行,因此不會出現i is not defined
死區是說,let 定義的變量,不能在聲明前使用。

(function(){
    console.log(1, i) //1 4 
    //4來源於上面的測試例子,否則會是下面這個鬼樣子
    //Uncaught ReferenceError: i is not defined
})();
(function(){
    console.log(2, i)
    var i  = 'lilnong.top' //2 undefined
})();
(function(){
    console.log(3, i)
    let i = 'lilnong.top' // Uncaught ReferenceError: Cannot access 'i' before initialization
})();

globalThis

  • 瀏覽器裏面,頂層對象是window,但 Node 和 Web Worker 沒有window
  • 瀏覽器和 Web Worker 裏面,self也指向頂層對象,可是 Node 沒有self
  • Node 裏面,頂層對象是global,但其餘環境都不支持。

因此提供了一個訪問頂層對象的屬性。

解構、默認值

  1. 數組解構賦值 let [a, b, c] = [1, 2, 3];
  2. 對象解構賦值 let { foo, bar } = { foo: 'aaa', bar: 'bbb' }
  3. 字符串解構賦值 const [a, b, c, d, e] = 'hello'
  4. 函數參數的解構賦值(這個比較經常使用)

    axios('https://www.lilnong.top/cors/axios-destructuring')
    .then(({data})=>console.log(data))
    // y取默認值,而後入參第一個的默認值是{}
    function move({x = 0, y = 0} = {}) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, 0]
    move({}); // [0, 0]
    move(); // [0, 0]
    // y沒有默認值,第一個入參的默認值是{ x: 0, y: 0 }
    function move({x, y} = { x: 0, y: 0 }) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, undefined]
    move({}); // [undefined, undefined]
    move(); // [0, 0]

字符串的擴展、模板字符串、unicode

字符串擴展

只能說寫起來更爽了。而後就是以前的寫法其實不是很好。會浪費空間,效率不高。
${Math.random()}-${Date.now()}-lilnong.top

unicode 更好的支持、codePointAt、fromCodePoint、normalize

面向國際化,以及 emoji。JavaScript 內部,字符以 UTF-16 的格式儲存,每一個字符固定爲2個字節。對於那些須要4個字節儲存的字符(Unicode 碼點大於0xFFFF的字符),JavaScript 會認爲它們是兩個字符。

這裏有個小插曲,weex 中 Text 組件沒法包含 Image 組件,實現流式排列。(富文本組件好像是能夠解決)

在實現這個功能的時候,我想到能夠把字變成塊,而後flex 容許換行。
測試地址,裏面用了兩種方案來獲取大於Oxffff的字符。

  1. for of
  2. codePointAt 判斷大於0xFFFF,須要跳字節。charCodeAt是ES5就支持的,只能拿到小於OxFFFF

更多的API

includes、startsWith、endsWith、repeat、padStart、padEnd、trimStart、trimEnd、matchAll
隨着原生提供的 API 愈來愈多,咱們慢慢的不須要使用 Loadsh 等工具庫。

正則表達式的擴展、斷言、unicode

後行斷言

JavaScript 語言的正則表達式,只支持先行斷言(lookahead)和先行否認斷言(negative lookahead),不支持後行斷言(lookbehind)和後行否認斷言(negative lookbehind)。ES2018 引入 後行斷言,V8 引擎 4.9 版(Chrome 62)已經支持。
「先行斷言」指的是, x只有在 y前面才匹配,必須寫成 /x(?=y)/。好比,只匹配百分號以前的數字,要寫成 /\d+(?=%)/。「先行否認斷言」指的是, x只有不在 y前面才匹配,必須寫成 /x(?!y)/。好比,只匹配不在百分號以前的數字,要寫成 /\d+(?!%)/
ECMAScript 6 入門 - 後行斷言 - 阮一峯

數值的擴展、API、指數運算符

更多的API Number.isFinite()、Number.isNaN()、Number.parseInt()、Number.parseFloat()、Number.isInteger()、Number.isSafeInteger()、Number.EPSILON、Number.isSafeInteger()

函數的擴展、默認值、rest參數、箭頭函數、尾調用優化

尾調用優化

咱們知道,函數調用會在內存造成一個「調用記錄」,又稱「調用幀」(call frame),保存調用位置和內部變量等信息。若是在函數 A的內部調用函數 B,那麼在 A的調用幀上方,還會造成一個 B的調用幀。等到 B運行結束,將結果返回到 AB的調用幀纔會消失。若是函數 B內部還調用函數 C,那就還有一個 C的調用幀,以此類推。全部的調用幀,就造成一個「調用棧」(call stack)。
遞歸很是耗費內存,由於須要同時保存成千上百個調用幀,很容易發生「棧溢出」錯誤(stack overflow)。但對於尾遞歸來講,因爲只存在一個調用幀,因此永遠不會發生「棧溢出」錯誤。

rest參數

(()=>arguments)(1,2,3) // 輸出什麼?Uncaught ReferenceError: arguments is not defined

在兼容函數中arguments沒法使用

((...args)=>args)(1,2,3) //有輸出什麼?[1, 2, 3]

咱們可使用...來把入參收集起來

((a,...args)=>args)(1,2,3) //[2, 3]

甚至咱們前面用變量接收,後面總體用...接收

箭頭函數

  1. this 指向定義時所在的對象
  2. 不可使用 arguments 對象

數組的擴展、展開運算符、API、空位的處理

展開

舉一個例子你就知道了。去重,雖然這個方法有侷限性吧。
[...new Set([12, 2, 3, 12, 31, 2, 11, 2, 1, 2, 1, 21, 1, 2, 3, 1, 23, 12, 3, 12, 31, 11, 1, 2, 2, 31, 2, 3])]

數組的API

Array.from()、Array.of()、Array.prototype.copyWithin()、Array.prototype.find()、Array.prototype.findIndex()、Array.prototype.fill()、Array.prototype.entries()、Array.prototype.keys()、Array.prototype.values()、Array.prototype.includes()、Array.prototype.flat()、Array.prototype.flatMap()、

nodeList = document.querySelectorAll('div');
// ES5的寫法
[].slice.call(nodeList);
// ES6的寫法
Array.from(nodeList);

對象的擴展、縮寫、變量名錶達式、展開運算符、API

變量名錶達式

當我看到下面的寫法的時候,心裏是臥槽的。

GET_USER_INFO = 'getBaseUserInfo'
obj = {
    [GET_USER_INFO](){// 第一次看到是vuex裏面分開定義獲取數據
        console.log(arguments)
    },
    'abc.sdf'(){// vue watch監聽改變的時候
        console.log(arguments)
    }
}

image.png

API

Object.is()、Object.assign()、Object.getOwnPropertyDescriptors()、Object.setPrototypeOf()、Object.getPrototypeOf()、Object.keys()、Object.values()、Object.entries()、Object.fromEntries()

新的類型、新的全局對象

Symbol、Set、Map、Proxy、Reflect、Promise、Iterator、Generator、async、Class、Module
簡直了。太多了

微信公衆號:前端linong

clipboard.png

參考文獻

  1. 前端培訓目錄、前端培訓規劃、前端培訓計劃
相關文章
相關標籤/搜索