Js高級程序設計-學習筆記(chapter 9)

最近公司在組織前端團隊學習JavaScript高級程序設計(第四版)。這兩天把第九章看完了,如下是精簡版的學習筆記:前端

本章要點:

  1. proxy是代理的意思, 能夠經過 構造函數 Proxy,給目標對象targetObj建立一個代理對象
  2. 對代理對象執行操做,會走handler裏的方法,對源對象執行操做,不會
  3. 代理能夠捕獲13中不一樣的基礎api,handler中可定義多個捕獲方法
  4. 是一個全局的Reflect對象,全部捕獲的方法都有對應的Reflect api方法。它與捕獲器攔截的方法同名、行爲相同。
  5. Reflect api 不限於捕獲處理程序handler,也可用在處理普通對象上
  6. 大多數Reflect api在Object上有對應的方法
  7. 有了Reflect後,能夠方便寫捕獲器
  8. 代理模式的幾種應用

proxy

what?(Proxy是什麼?)

proxy是代理的意思, 能夠經過 構造函數 Proxy,給目標對象targetObj建立一個代理對象。api

const proxyObj = new Proxy(targetObj, handlerObj)

能夠給對象obj建立一個代理。數組

why?(爲何用Proxy?)

當對代理對象進行一些對象操做時,會先執行代理中handlerObj對象定義的方法。app

好比:ide

get( ) // 取對象屬性
set( ) // 往對象中添加屬性

how?(怎麼用Proxy?)

對代理對象執行操做,會走handler裏的方法函數

對源對象執行操做,不會走handler裏的方法學習

const target = {foo: "bar"}
const handler = {
    get(target, prop, receiver){ // get()是一個捕獲器,其參數分別表明:目標對象、目標屬性、代理對象。每一個捕獲器入參不一樣。
        return "handle override"
    }
}
const proxyObj = new Proxy(target,handler)
console.log(proxyObj.foo) // "handle override",執行handler
console.log(target.foo) // "bar",沒有執行handler

Reflect

what?(Reflect是什麼?)

是一個全局的Reflect對象,全部捕獲的方法都有對應的Reflect api方法。它與捕獲器攔截的方法同名、行爲相同。this

Reflect api 不限於捕獲處理程序handler設計

大多數Reflect api在Object上有對應的方法。代理

why?(爲何用Reflect?)

有了Reflect後,能夠方便寫捕獲器。

看例子:

const target = {foo: "bar"}
const handler = {
    get(target, prop, receiver){
        return Reflect.get(...arguments)
    }
}
const proxyObj = new Proxy(target,handler)

Reflect api會提供一些狀態標記。

Reflect.set() ,Reflect.defineProperty()會返回布爾值。

Reflect api可利用一等函數替換操做符。Reflect.has( )

const obj = {name: "cc"}
const target = Object.create(obj)
target.age = 12
if(Reflect.has(target, "name")) { // 親測和對象的in操做符效果相同,均可以獲取對象原型鏈上的屬性
  console.log("wow, I have!")
}

how?(怎麼用Reflect?)

以上,寫捕獲器的時候能夠用,利用它的返回值,在對象上也能夠用

代理捕獲器和對應的反射方法

代理能夠捕獲13中不一樣的基礎api。

get() 獲取屬性時

set() 設置屬性值

has() 對象執行in操做時

defineProperty( )

getOwnPropertyDescriptor()

deleteProperty()

ownKeys()

getPrototypeOf()

setPropotypeOf()

isExtensible()

preentExtensions()

apply()

construct()

代理模式的幾種應用

  1. 跟蹤屬性訪問

經過捕獲get、set 和has 等操做,能夠知道對象屬性何時被訪問、被查詢。

  1. 隱藏屬性
  2. 屬性驗證

set()裏面寫捕獲器,驗證對象的賦值操做是否合法

例子:

setObjDataEmpty = (paramObj) => {
  const proxy = new Proxy(paramObj, {
    set(target, prop) {
      const oldVal = target[prop]
      if(typeof oldVal === "string") { // 字符串,直接賦值
        return Reflect.set(...arguments)
      }else if(Array.isArray(oldVal)){
        return Reflect.set(target, prop, []) // 數組,置空
      }else{
        return false // 都不是,賦值失敗
      }
    }
  })
  Object.keys(proxy).forEach(key => {
    proxy[key] = ""
  })
  return proxy
}
  1. 函數和構造函數的參數驗證
consructor = () => {
  class SetId {
    constructor(id) {
      this.id = id
    }
  }
  const pSetId = new Proxy(SetId, {
    construct(target, argumentList) {
      if(argumentList[0] === undefined) {
        throw("oh, you must put id!")
      }else{
        return Reflect.construct(...arguments)
      }
    }
  })
  const id1 = new pSetId("1") 
  console.log(id1)  // {id: '1'}
  const id2 = new pSetId() //  Uncaught oh, you must put id!
  console.log(id2) 
}
  1. 數據綁定與可觀察對象
const userList = [];
  class User {
    constructor(name) {
      this.name = name;
    }
  }
  const proxy = new Proxy(User, {
    construct() {
      const newUser = Reflect.construct(...arguments);
      userList.push(newUser);
      return newUser;
    }
  });
  new proxy('John');
  new proxy('Jacob');
  new proxy('Jingleheimerschmidt');
  console.log(userList);
相關文章
相關標籤/搜索