站長資訊網
        最全最豐富的資訊網站

        深入淺析ES6中的Proxy(代理)

        深入淺析ES6中的Proxy(代理)

        創建一個簡單的Proxy

        let target = {} let proxy = new Proxy(target, {})  proxy.name = 'proxy'  console.log(proxy.name) // proxy console.log(target.name) // proxy  target.name = 'target'  console.log(proxy.name) // target console.log(target.name) // target

        這個實例將"proxy"賦值給proxy.name屬性時會在目標上創建name,代理只是簡單的將操作轉發給目標,他不會儲存這個屬性。相當于proxy.name和target.name引用的都是target.name的值。

        使用set陷阱驗證屬性

        set陷阱接收四個參數:

        1.trapTarget:用于接收屬性(代理的目標)的對象

        2.key:要寫入的屬性鍵(字符串或者symbol)

        3.value:被寫入的屬性值

        4.receiver:操作發生的對象(通常是代理)

        let target = {     name: "target" }  let proxy = new Proxy(target, {     set(trapTarget, key, value, receiver) {         if (!trapTarget.hasOwnProperty(key)) {             if (isNaN(value)) {                 throw new TypeError("屬性必須時數字")             }         }          return Reflect.set(trapTarget, key, value, receiver)     } })  proxy.count = 1 console.log(proxy.count) //1 console.log(target.count) //1  proxy.name = "proxy"  console.log(proxy.name) //proxy console.log(target.name) //proxy  proxy.other = "other" // 這里會報錯因為不數字

        這個實例每次在外面改變proxy的值時就會出發set函數。

        用get陷阱驗證對象結構

        get接收3個參數

        1.trapTarget:用于接收屬性(代理的目標)的對象

        2.key:要寫入的屬性鍵(字符串或者symbol)

        3.receiver:操作發生的對象(通常是代理)

        let proxy = new Proxy({}, {     get(trapTarget, key, receiver) {         if (!(key in receiver)) {             throw new TypeError("屬性" + key + "不存在")         }          return Reflect.get(trapTarget, key, receiver)     } })  proxy.name = "proxy"  console.log(proxy.name) //proxy  console.log(proxy.age) // 屬性不存在會拋出錯誤

        當我們訪問proxy創建的對象屬性時就會觸發get方法

        使用has陷阱因此已有屬性

        has接收2個參數:

        1.trapTarget:用于接收屬性(代理的目標)的對象

        2.key:要寫入的屬性鍵(字符串或者symbol)

        let target = {     name: "target",     value: 42 }  let proxy = new Proxy(target, {     has(trapTarget, key) {         if (key === 'value') {             return false         } else {             return Reflect.has(trapTarget, key)         }     } })   console.log("value" in proxy) // false console.log("name" in proxy) // true console.log("toString" in proxy) // true

        用deleteProperty陷阱防止刪除屬性

        deleteProperty接收2個參數:

        1.trapTarget:用于接收屬性(代理的目標)的對象

        2.key:要寫入的屬性鍵(字符串或者symbol)

        let target = {     name: "target",     value: 42 }  let proxy = new Proxy(traget, {     deleteProperty(trapTarget, key) {         if (key === "value") {             return false         } else {             return Reflect.deleteProperty(trapTarget, key)         }     } })   console.log("value" in proxy) // true  let result1 = delete proxy.value  console.log(result1) // false console.log("value" in proxy) // true  console.log("name" in proxy) // true  let result2 = delete proxy.name console.log(result2) // true console.log("name" in proxy) // false

        當外部要刪除proxy的屬性就會觸發deleteProperty函數

        原型代理陷阱(setProptotypeOf,getPrototypeOf)

        setProptotypeOf接收2個參數

        1.trapTarget:用于接收屬性(代理的目標)的對象

        2.proto:作為原型使用的對象

        let target = {}  let proxy = new Proxy(target, {      // 訪問時調用     getPrototypeOf(trapTarget) {         return null     },     // 改變時調用     setPrototypeOf(trapTarget, proto) {         return false     }  })  let targetProto = Object.getPrototypeOf(target) let proxyProto = Object.getPrototypeOf(proxy)  console.log(targetProto === Object.prototype) //true console.log(proxyProto === Object.prototype) // false console.log(proxyProto) // null  Object.setPrototypeOf(target, {}) // 成功  Object.setPrototypeOf(proxy, {}) // 拋出錯誤

        如果正常實現

        let target = {}  let proxy = new Proxy(target, {      // 訪問時調用     getPrototypeOf(trapTarget) {         return Reflect.getPrototypeOf(trapTarget)     },     // 改變時調用     setPrototypeOf(trapTarget, proto) {         return Reflect.setPrototypeOf(trapTarget, proto)     }  })  let targetProto = Object.getPrototypeOf(target) let proxyProto = Object.getPrototypeOf(proxy)  console.log(targetProto === Object.prototype) //true console.log(proxyProto === Object.prototype) // true  Object.setPrototypeOf(target, {}) // 成功  Object.setPrototypeOf(proxy, {}) // 成功

        屬性描述符陷阱

        defineProperty接收三個參數:

        1.trapTarget:用于接收屬性(代理的目標)的對象

        2.key:要寫入的屬性鍵(字符串或者symbol)

        3.descriptor:屬性的描述對象

        let proxy = new Proxy({}, {     defineProperty(trapTarget, key, descriptor) { // descriptor 只能接收enumerable, configurable, value, writeable, get, set          if (typeof key === "symbol") {             return false         }         return Reflect.defineProperty(trapTarget, key, descriptor)     },     getOwnPropertyDescriptor(trapTarget, key) {         return Reflect.getOwnPropertyDescriptor(trapTarget, key)     } })  Object.defineProperty(proxy, "name", {     value: "proxy" })  console.log(proxy.name) //proxy  let nameSymbol = Symbol("name")  Object.defineProperty(proxy, nameSymbol, {     value: "proxy" })

        在外部調用defineProperty | getOwnPropertyDescriptor時會觸發內部definenProperty | getOwnPropertyDescriptor方法。

        ownKeys陷阱

        ownKeys陷阱會攔截外部的Object.keys(),Object.getOwnPropertyName(),Object.getOwnPropertySymbols()和Object.assign()四個方法

        let proxy = new Proxy({}, {     ownKeys(trapTarget) {         return Reflect.ownKeys(trapTarget).filter(key => {             return typeof key !== "string" || key[0] !== '_'         })     } })  let nameSymbol = Symbol("name")  proxy.name = "proxy"  proxy._name = "private"  proxy[nameSymbol] = "symbol"  let names = Object.getOwnPropertyNames(proxy),     keys = Object.keys(proxy),     symbols = Object.getOwnPropertySymbols(proxy)  console.log(names.length) // 1 console.log(names) // name  console.log(keys.length) //1 console.log(keys[0]) // name  console.log(symbols.length) //1 console.log(symbols[0]) // symbol(name)

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产成人精品久久综合| 久久精品国产国产精品四凭| 亚洲精品自产拍在线观看动漫| 青草国产精品视频。| 66精品综合久久久久久久| 亚洲综合一区二区精品导航| 国语自产拍精品香蕉在线播放| 亚洲精品字幕在线观看| 国产精品福利片免费看| 国产观看精品一区二区三区| 国产系列高清精品第一页 | 亚洲精品成人无限看| 亚洲日韩国产AV无码无码精品 | 精品人无码一区二区三区| 2020久久精品国产免费| 午夜精品福利视频| 亚洲国产综合精品中文字幕 | 国产2021久久精品| 亚洲七七久久精品中文国产| 国产99视频精品免费专区| 国产精品小黄鸭一区二区三区| 永久无码精品三区在线4| 四虎永久在线精品884aa下载| 宅男在线国产精品无码| 四虎国产精品永久一区| 亚洲国产精品一区二区久久hs| 91亚洲国产成人久久精品| 日韩人妻无码精品久久免费一| 国产成人精品久久亚洲| 亚洲高清专区日韩精品| 一区二区三区日韩精品| 日韩精品无码中文字幕一区二区| 国产午夜精品理论片久久| 亚洲AV日韩精品久久久久久久| 91av国产精品| 国产精品白丝AV网站| 中文字幕精品无码一区二区三区 | 99久久精品免费看国产一区二区三区| 亚洲国产精品无码久久久蜜芽 | 97精品人妻一区二区三区香蕉| 久久丫精品国产亚洲av不卡|