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

        深入淺析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號
        主站蜘蛛池模板: 2021国产三级精品三级在专区| 久久亚洲精品视频| 国产精品2019| 亚洲精品无码久久千人斩| 国产三级精品三级在专区| 2022国内精品免费福利视频| 综合人妻久久一区二区精品| 国产一区二区三区欧美精品| 亚洲第一精品福利| 国产小视频国产精品| 国产精品水嫩水嫩| 无码人妻精品一区二区三区99仓本| 国产综合精品久久亚洲 | 91精品国产品国语在线不卡| 精品无码人妻夜人多侵犯18| 亚洲AV永久无码精品成人| 最新国产精品拍自在线播放| 亚洲国产精品成人| 亚洲人成电影网站国产精品| 欧美在线精品永久免费播放| 久久久久久久久久免免费精品| 国产久爱免费精品视频| 国产午夜精品理论片免费观看| 99久久精品免费国产大片| 青青草国产精品久久| 久久精品九九亚洲精品天堂| 久久99精品综合国产首页| 国产精品夜色一区二区三区| 久久精品国产亚洲麻豆| 久久er国产精品免费观看2| 国产精品爽爽va在线观看网站| 国产精品久久永久免费| 国产精品久久影院| 亚洲自偷自偷精品| 99re66在线观看精品免费| 久久精品国产亚洲综合色| 久久se精品一区精品二区| 亚洲愉拍自拍欧美精品| 国产伦精品一区二区三区视频猫咪| 国产一区二区三精品久久久无广告| 狠狠色伊人久久精品综合网|