最近公司在組織前端團隊學習JavaScript高級程序設計(第四版)。這兩天把第九章看完了,如下是精簡版的學習筆記:前端
proxy是代理的意思, 能夠經過 構造函數 Proxy,給目標對象targetObj建立一個代理對象。api
const proxyObj = new Proxy(targetObj, handlerObj)
能夠給對象obj建立一個代理。數組
當對代理對象進行一些對象操做時,會先執行代理中handlerObj對象定義的方法。app
好比:ide
get( ) // 取對象屬性 set( ) // 往對象中添加屬性
對代理對象執行操做,會走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對象,全部捕獲的方法都有對應的Reflect api方法。它與捕獲器攔截的方法同名、行爲相同。this
Reflect api 不限於捕獲處理程序handler設計
大多數Reflect api在Object上有對應的方法。代理
有了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!") }
以上,寫捕獲器的時候能夠用,利用它的返回值,在對象上也能夠用
代理能夠捕獲13中不一樣的基礎api。
get() 獲取屬性時
set() 設置屬性值
has() 對象執行in操做時
defineProperty( )
getOwnPropertyDescriptor()
deleteProperty()
ownKeys()
getPrototypeOf()
setPropotypeOf()
isExtensible()
preentExtensions()
apply()
construct()
經過捕獲get、set 和has 等操做,能夠知道對象屬性何時被訪問、被查詢。
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 }
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) }
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);