亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

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

    使用set陷阱驗證屬性

    set陷阱接收四個參數(shù):

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

    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("屬性必須時數(shù)字")             }         }          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" // 這里會報錯因為不數(shù)字

    這個實例每次在外面改變proxy的值時就會出發(fā)set函數(shù)。

    用get陷阱驗證對象結(jié)構(gòu)

    get接收3個參數(shù)

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

    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) // 屬性不存在會拋出錯誤

    當(dāng)我們訪問proxy創(chuàng)建的對象屬性時就會觸發(fā)get方法

    使用has陷阱因此已有屬性

    has接收2個參數(shù):

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

    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個參數(shù):

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

    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

    當(dāng)外部要刪除proxy的屬性就會觸發(fā)deleteProperty函數(shù)

    原型代理陷阱(setProptotypeOf,getPrototypeOf)

    setProptotypeOf接收2個參數(shù)

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

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

    let target = {}  let proxy = new Proxy(target, {      // 訪問時調(diào)用     getPrototypeOf(trapTarget) {         return null     },     // 改變時調(diào)用     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, {}) // 拋出錯誤

    如果正常實現(xiàn)

    let target = {}  let proxy = new Proxy(target, {      // 訪問時調(diào)用     getPrototypeOf(trapTarget) {         return Reflect.getPrototypeOf(trapTarget)     },     // 改變時調(diào)用     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接收三個參數(shù):

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

    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" })

    在外部調(diào)用defineProperty | getOwnPropertyDescriptor時會觸發(fā)內(nèi)部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)
    網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號