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

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

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

        創(chuàng)建一個簡單的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屬性時會在目標上創(chuàng)建name,代理只是簡單的將操作轉發(fā)給目標,他不會儲存這個屬性。相當于proxy.name和target.name引用的都是target.name的值。

        使用set陷阱驗證屬性

        set陷阱接收四個參數:

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

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

        3.value:被寫入的屬性值

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

        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的值時就會出發(fā)set函數。

        用get陷阱驗證對象結構

        get接收3個參數

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

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

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

        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創(chuàng)建的對象屬性時就會觸發(fā)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的屬性就會觸發(fā)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時會觸發(fā)內部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號
        主站蜘蛛池模板: 久久精品国产亚洲av水果派| 少妇人妻偷人精品视频| 亚洲精品国产高清不卡在线| 国产欧美久久久精品| 亚洲码国产精品高潮在线| 国产精品自产拍高潮在线观看| 国产精品9999久久久久| 无码国模国产在线无码精品国产自在久国产 | 久久久久夜夜夜精品国产| 欧美精品亚洲精品日韩传电影| 久久精品一区二区影院| 成人精品一区二区三区在线观看| 国产精品扒开腿做爽爽爽视频| 亚洲精品天堂成人片?V在线播放| 精品国产亚洲一区二区在线观看| 日韩欧国产精品一区综合无码| 91麻豆精品国产自产在线观看亚洲| 久久99热只有频精品8| 欧美国产成人久久精品| 精品伦精品一区二区三区视频 | 久久成人影院精品777| 国产精品综合色区在线观看| 无码精品人妻一区二区三区免费看 | 亚洲AV日韩精品久久久久久| 亚洲国产精品无码久久九九| 日本精品久久久久久久久免费| 精品国产亚洲男女在线线电影| 国产精品一香蕉国产线看观看 | 中文字幕亚洲综合精品一区| 久久精品国产亚洲麻豆| 国产精品欧美久久久天天影视| 国产午夜福利精品一区二区三区 | 国产亚洲精品精品国产亚洲综合| 99久久精品费精品国产| 亚洲精品欧美综合| 99R在线精品视频在线播放| 99久久99久久精品国产| 国产精品videossex白浆| 亚洲精品麻豆av| 国产精品热久久无码av| 国产福利精品视频自拍|