前端最基礎的就是 HTML+CSS+Javascript
。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS
),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。javascript
放開我,我又要吐槽了。看到這個題目的時候,我十分的頭禿。
那麼我爲何頭禿呢?html
其實還有一個誤區不是ES5的都歸ES6。
其實想一想挺逗的。爲何會有這樣一個誤區?ES2015出來的時候瀏覽器廠商支持就不同,ES2016出來以後支持仍是不同,ES201七、ES201八、ES2019 都是這樣。這就出現了一個問題,發布是發佈了,可是啥時候支持就不必定了。
這裏放出來我前兩天才看的文章,他們的更新速度是真的恐怖。前端
從提案到正式標準,須要經歷五個階段。每一個階段的變更都須要由 TC39 委員會批准。vue
當前的全部提案,能夠在 TC39 的官方網站查看。java
Babel 是一個 JavaScript 編譯器。將 ECMAScript 2015+ 版本的代碼轉換爲向後兼容的 JavaScript 語法,以便可以運行在當前和舊版本的瀏覽器或其餘環境中。下面列出的是 Babel 能作的事情:node
.babelrc
{ // presets字段設定轉碼規則 "presets": ["es2015", "react", "stage-2"], // 插件 "plugins": ["transform-decorators-legacy", "transform-class-properties"] }
官方已經針對經常使用環境編寫了一些 preset:react
Babel 默認只轉換新的 JavaScript 句法(syntax),而不轉換新的 API,好比 Iterator
、Generator
、Set
、Map
、Proxy
、Reflect
、Symbol
、Promise
等全局對象,以及一些定義在全局對象上的方法(好比Object.assign
、Array.includes
)都不會轉碼。ios
因此咱們還須要使用 babel-polyfill
。git
後面的東西其實看不看無所謂,想要學習呢,仍是看阮一峯大佬的好了。
我這裏說一下我認爲ES6更新了一些什麼東西。es6
在以前沒有塊級做用域的概念(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 })();
window
,但 Node 和 Web Worker 沒有window
。self
也指向頂層對象,可是 Node 沒有self
。global
,但其餘環境都不支持。因此提供了一個訪問頂層對象的屬性。
let [a, b, c] = [1, 2, 3];
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }
const [a, b, c, d, e] = 'hello'
函數參數的解構賦值(這個比較經常使用)
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]
只能說寫起來更爽了。而後就是以前的寫法其實不是很好。會浪費空間,效率不高。${Math.random()}-${Date.now()}-lilnong.top
面向國際化,以及 emoji
。JavaScript 內部,字符以 UTF-16 的格式儲存,每一個字符固定爲2
個字節。對於那些須要4
個字節儲存的字符(Unicode 碼點大於0xFFFF
的字符),JavaScript 會認爲它們是兩個字符。
這裏有個小插曲,weex 中 Text 組件沒法包含 Image 組件,實現流式排列。(富文本組件好像是能夠解決)
在實現這個功能的時候,我想到能夠把字變成塊,而後flex 容許換行。
測試地址,裏面用了兩種方案來獲取大於Oxffff
的字符。
0xFFFF
,須要跳字節。charCodeAt
是ES5就支持的,只能拿到小於OxFFFF
。includes、startsWith、endsWith、repeat、padStart、padEnd、trimStart、trimEnd、matchAll
隨着原生提供的 API 愈來愈多,咱們慢慢的不須要使用 Loadsh 等工具庫。
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 Number.isFinite()、Number.isNaN()、Number.parseInt()、Number.parseFloat()、Number.isInteger()、Number.isSafeInteger()、Number.EPSILON、Number.isSafeInteger()
咱們知道,函數調用會在內存造成一個「調用記錄」,又稱「調用幀」(call frame),保存調用位置和內部變量等信息。若是在函數A
的內部調用函數B
,那麼在A
的調用幀上方,還會造成一個B
的調用幀。等到B
運行結束,將結果返回到A
,B
的調用幀纔會消失。若是函數B
內部還調用函數C
,那就還有一個C
的調用幀,以此類推。全部的調用幀,就造成一個「調用棧」(call stack)。
遞歸很是耗費內存,由於須要同時保存成千上百個調用幀,很容易發生「棧溢出」錯誤(stack overflow)。但對於尾遞歸來講,因爲只存在一個調用幀,因此永遠不會發生「棧溢出」錯誤。
(()=>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]
甚至咱們前面用變量接收,後面總體用...
接收
this
指向定義時所在的對象arguments
對象舉一個例子你就知道了。去重,雖然這個方法有侷限性吧。[...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])]
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);
當我看到下面的寫法的時候,心裏是臥槽的。
GET_USER_INFO = 'getBaseUserInfo' obj = { [GET_USER_INFO](){// 第一次看到是vuex裏面分開定義獲取數據 console.log(arguments) }, 'abc.sdf'(){// vue watch監聽改變的時候 console.log(arguments) } }
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
簡直了。太多了