前端最基礎的就是 HTML+CSS+Javascript
。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS
),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。javascript
這節標題超長了,難受箭頭函數、set、map、proxy、symbol、reflect、generator前端
以前聲明函數使用 function funName(arg1,...args){return args}
。
ES6 增長了新的聲明函數方式 (arg1,...args)=>args
。vue
簡潔。[1,2,3,4,0,-1,-2,-3].map(v=>Math.sign(v))
java
...
)、解構({status, response}
)都須要加括號。 return
。若是有花括號,就須要顯式的return
,固然也能夠不寫默認 return
是 undefined
。this 指向。es6
this
對象指向定義時所在的對象,而不是使用時所在的對象。this
對象是不可變的。bind、call、apply、賦值等操做都沒法改變。arguments
。Generator
函數。不可使用 yield
命令不該該在聲明對象的時候使用。由於這個時候裏面的 this
指向定義時的環境。編程
obj = { name: 'app', jumps: () => { console.log(this.app); } }
Set
特色是值惟一和有序。相似於數組,可是成員的值都是惟一的,沒有重複的值,遍歷的話是插入順序。Array.from(new Set([1,2,3,1,1,2,3,1]))
依賴值惟一的特性實現去重。
segmentfault
new Set([iterable]);
使用可迭代的數組來建立。數組
new Set([1,2,3,4,2,1,1,1,12,3])
new Set('123123')
new Set(['123123',1,2,3])
new Set(document.querySelectorAll('a'))
Set.prototype.size
:返回總數,等價於(Array.prototype.length
)Set.prototype.add(value)
:添加,返回當前對象可鏈式操做。Set.prototype.delete(value)
:刪除,返回一個布爾值,表示刪除是否成功。Set.prototype.has(value)
:返回一個布爾值,表示該值是否爲Set的成員。Set.prototype.clear()
:清除全部成員,沒有返回值。Set.prototype.keys()
:返回鍵(key)的遍歷器 Iterator。Set.prototype.values()
:返回值(value)的遍歷器 Iterator。Set.prototype.entries()
:返回鍵值對([key, value])的遍歷器 Iterator。Set.prototype.forEach()
:使用回調函數(value, key, this)=>遍歷每一個成員
Map
其實 和 JavaScript 的對象(Object
)同樣,本質上是鍵值對的集合(Hash 結構)。
可是傳統上 Object
只能用字符串看成鍵,在使用上有很大的侷限性。微信
Map
的數據結構也能夠理解爲對象,是鍵值對的集合。
可是 key
的範圍不限於字符串,能夠是其餘類型(包括對象)均可以看成鍵。是一種更完善的 Hash
結構實現。數據結構
userinfo = {name: 'lilnong.top'} map = new Map() map.set(userinfo, {age: 123}) map.has(userinfo) map.get(userinfo)
map = new Map([ ['key1', 'value1'], ['key2', 'value2'] ]); map.forEach( (key, value) => console.log(key, value) );
size
返回記錄總數。(Object
但是沒有這個屬性的喲)set(key, value)
賦值操做get(key)
取值操做has(key)
判斷當前 key
是否存在於集合中。delete(key)
刪除操做。返回 true
,代表刪除成功。返回 false
代表刪除失敗,好比你刪除了一個不存在的 key
。clear()
清空全部。遍歷方法。(插入順序)
Map.prototype.keys()
:返回鍵名的遍歷器。Map.prototype.values()
:返回鍵值的遍歷器。Map.prototype.entries()
:返回全部成員的遍歷器。Map.prototype.forEach()
:遍歷 Map 的全部成員。WeakMap
只接受對象做爲鍵名(null
除外),不接受其餘類型的值做爲鍵名。WeakMap
的鍵名所指向的對象,不計入垃圾回收機制。
由於是弱引用,因此沒有遍歷方法、沒有 size,不支持 clear()。
Proxy
用於修改操做(getset)的默認行爲。
說到這裏是否是想到了 Object.defineProperty
?其實也和 JavaBean
那種操做 getter、setter
差很少。
等同於在語言層面作出修改,對編程語言進行編程,屬於一種「元編程」(meta programming )。
Proxy 能夠理解成,在目標對象以前架設個代理,對該對象的訪問,都必須先經過代理,這樣能夠對外界的訪問進行過濾和改寫。
vue 2.x 基於 Object.defineProperty
來實現的,可是會有一些場景監測不到(array.lenth、$set)。
vue 3.x 使用了 Proxy
來作了,能夠監測到更多的場景。固然,基於兼容性考慮仍是能夠回退到 Object.defineProperty
。
var obj = new Proxy({}, { get: function (target, propKey, receiver) { console.log(`getting ${propKey}!`); return Reflect.get(target, propKey, receiver); }, set: function (target, propKey, value, receiver) { console.log(`setting ${propKey}!`); return Reflect.set(target, propKey, value, receiver); } });
從下面這個例子咱們能夠看到,咱們能夠只設置讀的代理,無論讀取什麼都返回 www.lilnong.top
。而後咱們沒有設置寫的代理,值已經被真正的寫入了。
var proxy = new Proxy(target, handler);
key | arguments | 觸發時機 | demo |
---|---|---|---|
get |
(target, propKey, receiver) |
讀取屬性時觸發 | proxy.title 和 proxy['title'] |
set |
(target, propKey, value, receiver) |
設置屬性時觸發 | proxy.title = 'lilnong.top' 或 proxy['title'] = 'lilnong.top' |
has |
(target, propKey) |
in 時觸發 |
title in proxy |
deleteProperty |
(target, propKey) |
delete 時觸發 |
delete proxy.title |
ownKeys |
(target) |
獲取 key 合集時觸發 | Object.getOwnPropertyNames(proxy) 、Object.getOwnPropertySymbols(proxy) 、Object.keys(proxy) 、for...in |
getOwnPropertyDescriptor |
(target, propKey) |
讀取屬性時觸發 | Object.getOwnPropertyDescriptor(proxy, propKey) |
defineProperty |
(target, propKey, propDesc) |
讀取屬性時觸發 | Object.defineProperty(proxy, propKey, propDesc) 、Object.defineProperties(proxy, propDescs) |
preventExtensions |
(target) |
讀取屬性時觸發 | Object.preventExtensions(proxy) |
getPrototypeOf |
(target) |
讀取屬性時觸發 | Object.getPrototypeOf(proxy) |
isExtensible |
(target) |
讀取屬性時觸發 | Object.isExtensible(proxy) |
setPrototypeOf |
(target, proto) |
讀取屬性時觸發 | Object.setPrototypeOf(proxy, proto) |
apply |
(target, object, args) |
proxy 爲函數被調用時觸發 | proxy(...args) 、proxy.call(object, ...args) 、proxy.apply(...) |
construct |
(target, object, args) |
proxy 爲實例被New 時觸發 | new proxy(...args)) |
set
代理執行完畢應該返回 true
,不然會報錯。ES5 的 對象屬性名都是字符串,這容易形成屬性名的衝突。好比,你使用了一個他人提供的對象,但又想爲這個對象添加新的方法(mixin 模式),新方法的名字就有可能與現有方法產生衝突。若是有一種機制,保證每一個屬性的名字都是獨一無二的就行了,這樣就從根本上防止屬性名的衝突。這就是 ES6 引入Symbol
的緣由。ES6 引入了一種新的原始數據類型
Symbol
,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined
、null
、布爾值(Boolean
)、字符串(String
)、數值(Number
)、對象(Object
)。Symbol 值經過
Symbol
函數生成。這就是說,對象的屬性名如今能夠有兩種類型,一種是原來就有的字符串,另外一種就是新增的 Symbol 類型。凡是屬性名屬於 Symbol 類型,就都是獨一無二的,能夠保證不會與其餘屬性名產生衝突。
s = Symbol(); typeof s // "symbol" s1 = Symbol('foo'); s1 // Symbol(foo) s1.toString() // "Symbol(foo)" s2 = Symbol('bar'); s2 // Symbol(bar) s2.toString() // "Symbol(bar)"
Reflect
對象與Proxy
對象同樣,也是 ES6 爲了操做對象而提供的新 API。
Reflect
對象的設計目的有這樣幾個。(1) 將
Object
對象的一些明顯屬於語言內部的方法(好比Object.defineProperty
),放到Reflect
對象上。現階段,某些方法同時在Object
和Reflect
對象上部署,將來的新方法將只部署在Reflect
對象上。也就是說,從Reflect
對象上能夠拿到語言內部的方法。(2) 修改某些
Object
方法的返回結果,讓其變得更合理。好比,Object.defineProperty(obj, name, desc)
在沒法定義屬性時,會拋出一個錯誤,而Reflect.defineProperty(obj, name, desc)
則會返回false
。
....
.... https://es6.ruanyifeng.com/#d...
Generator
函數也是 ES6 提供的一種異步編程解決方案。如今通常都是 Promise
或者 await/async
,就不展開說了。
Generator 函數是 ES6 提供的一種異步編程解決方案,語法行爲與傳統函數徹底不一樣。本章詳細介紹 Generator 函數的語法和 API,它的異步編程應用請看《Generator 函數的異步應用》一章。Generator 函數有多種理解角度。語法上,首先能夠把它理解成,Generator 函數是一個狀態機,封裝了多個內部狀態。
執行 Generator 函數會返回一個遍歷器對象,也就是說,Generator 函數除了狀態機,仍是一個遍歷器對象生成函數。返回的遍歷器對象,能夠依次遍歷 Generator 函數內部的每個狀態。
形式上,Generator 函數是一個普通函數,可是有兩個特徵。一是,
function
關鍵字與函數名之間有一個星號;二是,函數體內部使用yield
表達式,定義不一樣的內部狀態(yield
在英語裏的意思就是「產出」)。....
.... https://es6.ruanyifeng.com/#d...