前端培訓-中級階段(32)- set、map、proxy、reflect、generator(2020-01-02期)

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

前言BB

這節標題超長了,難受箭頭函數、set、map、proxy、symbol、reflect、generator前端

箭頭函數

以前聲明函數使用 function funName(arg1,...args){return args}
ES6 增長了新的聲明函數方式 (arg1,...args)=>argsvue

箭頭函數的特色

  1. 匿名函數。經過上面例子能夠看出,匿名函數沒有名字。用法等價於以前的函數表達式
  2. 簡潔[1,2,3,4,0,-1,-2,-3].map(v=>Math.sign(v))java

    1. 入參的省略。若是隻有一個入參,那麼括號能夠省略。沒有入參、多個入參、rest 參數(...)、解構({status, response})都須要加括號。image.png
    2. 函數體的省略。若是沒有花括號,那麼只能傳入一個表達式,表達式的結果會 return。若是有花括號,就須要顯式的return,固然也能夠不寫默認 returnundefined
  3. this 指向es6

    1. 箭頭函數的 this 對象指向定義時所在的對象,而不是使用時所在的對象。
    2. 箭頭函數的 this 對象是不可變的。bind、call、apply、賦值等操做都沒法改變。
  4. 不能夠當作構造函數。由於上面的 this 問題。
  5. 沒有 arguments
  6. 不能用做 Generator 函數。不可使用 yield 命令

箭頭函數的一些錯誤用法

  1. 不該該在聲明對象的時候使用。由於這個時候裏面的 this 指向定義時的環境。編程

    obj = {
      name: 'app',
      jumps: () => {
        console.log(this.app);
      }
    }

Set、WeakSet

Set 特色是值惟一有序。相似於數組,可是成員的值都是惟一的,沒有重複的值,遍歷的話是插入順序。Array.from(new Set([1,2,3,1,1,2,3,1])) 依賴值惟一的特性實現去重。
image.pngsegmentfault

Set 構造函數

new Set([iterable]); 使用可迭代的數組來建立。數組

  1. new Set([1,2,3,4,2,1,1,1,12,3])
  2. new Set('123123')
  3. new Set(['123123',1,2,3])
  4. new Set(document.querySelectorAll('a'))
  5. image.png

屬性和方法

  1. Set.prototype.size:返回總數,等價於(Array.prototype.length
  2. Set.prototype.add(value):添加,返回當前對象可鏈式操做。
  3. Set.prototype.delete(value):刪除,返回一個布爾值,表示刪除是否成功。
  4. Set.prototype.has(value):返回一個布爾值,表示該值是否爲Set的成員。
  5. Set.prototype.clear():清除全部成員,沒有返回值。
  6. Set.prototype.keys():返回鍵(key)遍歷器 Iterator
  7. Set.prototype.values():返回值(value)遍歷器 Iterator
  8. Set.prototype.entries():返回鍵值對([key, value])遍歷器 Iterator
  9. Set.prototype.forEach():使用回調函數(value, key, this)=>遍歷每一個成員

WeakSet

  1. 只能存放對象的集合
  2. 弱引用方式保存。弱引用就是能夠被垃圾回收(若是放入數組,那麼你不知道什麼實際是能夠被回收的,由於數組是強引用),
  3. 沒有總數
  4. 不可枚舉

image.png

Map、WeakMap

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)

image.png

構造函數

map = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
]);
map.forEach(
  (key, value) => console.log(key, value)
);

image.png

屬性和方法

  1. size 返回記錄總數。(Object 但是沒有這個屬性的喲)
  2. set(key, value) 賦值操做
  3. get(key) 取值操做
  4. has(key) 判斷當前 key 是否存在於集合中。
  5. delete(key) 刪除操做。返回 true,代表刪除成功。返回 false 代表刪除失敗,好比你刪除了一個不存在的 key
  6. clear() 清空全部。
  7. 遍歷方法。(插入順序)

    • Map.prototype.keys():返回鍵名的遍歷器。
    • Map.prototype.values():返回鍵值的遍歷器。
    • Map.prototype.entries():返回全部成員的遍歷器。
    • Map.prototype.forEach():遍歷 Map 的全部成員。

weakMap

WeakMap 只接受對象做爲鍵名null除外),不接受其餘類型的值做爲鍵名。
WeakMap鍵名所指向的對象,不計入垃圾回收機制
由於是弱引用,因此沒有遍歷方法、沒有 size,不支持 clear()。

proxy

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。而後咱們沒有設置寫的代理,值已經被真正的寫入了。
image.png

構造函數

var proxy = new Proxy(target, handler);

支持代理的操做

key arguments 觸發時機 demo
get (target, propKey, receiver) 讀取屬性時觸發 proxy.titleproxy['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))

注意事項

  1. 嚴格模式下,set 代理執行完畢應該返回 true,不然會報錯。

symbol

ES5 的 對象屬性名都是字符串,這容易形成屬性名的衝突。好比,你使用了一個他人提供的對象,但又想爲這個對象添加新的方法(mixin 模式),新方法的名字就有可能與現有方法產生衝突。若是有一種機制,保證每一個屬性的名字都是獨一無二的就行了,這樣就從根本上防止屬性名的衝突。這就是 ES6 引入 Symbol的緣由。

ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefinednull、布爾值(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

Reflect對象與Proxy對象同樣,也是 ES6 爲了操做對象而提供的新 API。

Reflect對象的設計目的有這樣幾個。

(1) 將Object對象的一些明顯屬於語言內部的方法(好比Object.defineProperty),放到Reflect對象上。現階段,某些方法同時在ObjectReflect對象上部署,將來的新方法將只部署在Reflect對象上。也就是說,從Reflect對象上能夠拿到語言內部的方法。

(2) 修改某些Object方法的返回結果,讓其變得更合理。好比,Object.defineProperty(obj, name, desc)在沒法定義屬性時,會拋出一個錯誤,而Reflect.defineProperty(obj, name, desc)則會返回false
....
.... https://es6.ruanyifeng.com/#d...

generator

Generator 函數也是 ES6 提供的一種異步編程解決方案。如今通常都是 Promise 或者 await/async,就不展開說了。

Generator 函數是 ES6 提供的一種異步編程解決方案,語法行爲與傳統函數徹底不一樣。本章詳細介紹 Generator 函數的語法和 API,它的異步編程應用請看《Generator 函數的異步應用》一章。

Generator 函數有多種理解角度。語法上,首先能夠把它理解成,Generator 函數是一個狀態機,封裝了多個內部狀態。

執行 Generator 函數會返回一個遍歷器對象,也就是說,Generator 函數除了狀態機,仍是一個遍歷器對象生成函數。返回的遍歷器對象,能夠依次遍歷 Generator 函數內部的每個狀態。

形式上,Generator 函數是一個普通函數,可是有兩個特徵。一是,function關鍵字與函數名之間有一個星號;二是,函數體內部使用yield表達式,定義不一樣的內部狀態(yield在英語裏的意思就是「產出」)。

....
.... https://es6.ruanyifeng.com/#d...

微信公衆號:前端linong

clipboard.png

參考文獻

  1. 前端培訓目錄、前端培訓規劃、前端培訓計劃
  2. https://developer.mozilla.org/zh-CN/
  3. http://es6.ruanyifeng.com/
相關文章
相關標籤/搜索