av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

理解JavaScript中的Proxy 與 Reflection API

瀏覽:102日期:2023-10-12 11:17:19

一、創(chuàng)建 Proxy

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

在上面的例子中,由 Proxy 構(gòu)造器創(chuàng)建的 proxy 對象會將自身的所有操作直接轉(zhuǎn)發(fā)給 target。當(dāng) proxy.name 被賦值為 'proxy' 時,target 對象也會創(chuàng)建 name 屬性并獲得同樣的值。實(shí)際上 proxy 對象本身并不創(chuàng)建和存儲 name 屬性,它只是轉(zhuǎn)發(fā)對應(yīng)的操作給 target。

類似的,proxy.name 與 target.name 的值始終保持一致,因?yàn)樗鼈儗?shí)際上都指向了 target.name。這也意味著給 target.name 賦予一個新的值時,該變化也會反映到 proxy.name 上。

使用 set Trap 驗(yàn)證屬性

Proxy 允許開發(fā)者主動攔截本該轉(zhuǎn)發(fā)給 target 對象的底層操作,這些攔截行為通過 trap 實(shí)現(xiàn)。每個 trap 都可以覆蓋 JavaScript 對象的某些內(nèi)置行為,即 proxy 允許通過 trap 攔截并修改指向 target 對象的操作。

假設(shè)需要創(chuàng)建一個新添加的屬性值只能是數(shù)字類型的對象,就可以借助 set trap 覆蓋默認(rèn)的賦值行為。代碼如下:

let target = { name: 'target'}let proxy = new Proxy(target, { set(trapTarget, key, value, receiver) { if (!trapTarget.hasOwnProperty(key)) { if (isNaN(value)) { throw new TypeError('New property must be a number.') } } return Reflect.set(trapTarget, key, value, receiver) }})proxy.count = 1console.log(proxy.count) // 1console.log(target.count) // 1proxy.name = 'proxy'console.log(proxy.name) // proxyconsole.log(target.name) // proxyproxy.anotherName = 'proxy'// TypeError: New property must be a number.

set trap 中的四個參數(shù)含義如下:

trapTarget:接收新屬性的對象(即 proxy 指向的 target) key:新屬性對應(yīng)的 key value:新屬性對應(yīng)的 value receiver:通常為 proxy 自身

Reflect.set() 是與 set trap 相對應(yīng)的原始方法,表示被覆蓋前的默認(rèn)的賦值行為。

使用 get Trap 令程序讀取不存在屬性時報(bào)錯

JavaScript 在讀取不存在的屬性時并不會報(bào)錯,而是返回 undefined。

let target = {}console.log(target.name) // undefined

可以借助 get trap 修改讀取對象屬性時的默認(rèn)行為:

let proxy = new Proxy({}, { get(trapTarget, key, receiver) { if (!(key in receiver)) { throw new TypeError('Property ' + key + ' doesn’t exist.') } return Reflect.get(trapTarget, key, receiver) }})proxy.name = 'proxy'console.log(proxy.name) // proxyconsole.log(proxy.nme)// TypeError: Property nme doesn’t exist.

通過 deleteProperty Trap 防止刪除屬性

JavaScript 中使用 delete 操作符刪除對象的屬性:

let target = { name: 'target', value: 42}Object.defineProperty(target, 'name', { configurable: false })console.log('value' in target) // truelet result1 = delete target.valueconsole.log(result1) // trueconsole.log('value' in target) // falselet result2 = delete target.nameconsole.log(result2) // falseconsole.log('name' in target) // true

使用 deleteProxy Trap 防止屬性被意外刪除:

let target = { name: 'target', value: 42}let proxy = new Proxy(target, { deleteProperty(trapTarget, key) { if (key === 'value') { return false } else { return Reflect.deleteProperty(trapTarget, key) } }})console.log('value' in proxy) // truelet result1 = delete proxy.valueconsole.log(result1) // falseconsole.log('value' in proxy) // truelet result2 = delete proxy.nameconsole.log(result2) // trueconsole.log('name' in proxy) // false

二、Proxy 的現(xiàn)實(shí)應(yīng)用

logging

function makeLoggable(target) { return new Proxy(target, { get: (target, property) => { console.log('Reading ' + property) return target[property] }, set: (target, property, value) => { console.log('Writing value ' + value + ' to ' + property) target[property] = value } })}let ninja = { name: 'Yoshi' }ninja = makeLoggable(ninja)console.log(ninja.name)ninja.weapon = 'sword'// Reading name// Yoshi// Writing value sword to weapon

性能測試

function isPrime(number) { if (number < 2) { return false } for (let i = 2; i < number; i++) { if (number % i === 0) { return false } } return true}isPrime = new Proxy(isPrime, { apply: (target, thisArg, args) => { console.time('isPrime') const result = target.apply(thisArg, args) console.timeEnd('isPrime') return result }})console.log(isPrime(1358765377))// isPrime: 6815.107ms// true

自動添加屬性

function Folder() { return new Proxy({}, { get: (target, property) => { console.log('Reading ' + property) if(!(property in target)) { target[property] = new Folder() } return target[property] } })}const rootFolder = new Folder()rootFolder.ninjasDir.firstNinjaDir.ninjaFile = 'yoshi.txt'// Reading ninjasDir// Reading firstNinjaDirconsole.log(rootFolder.ninjasDir.firstNinjaDir.ninjaFile)// Reading ninjasDir// Reading firstNinjaDir// Reading ninjaFile// yoshi.txt

參考資料

https://leanpub.com/understandinges6

https://www.manning.com/books/secrets-of-the-javascript-ninja-second-edition

以上就是理解JavaScript中的Proxy 與 Reflection API的詳細(xì)內(nèi)容,更多關(guān)于JavaScript中的Proxy 與 Reflection API的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 在线观看欧美日韩 | 成人久久av | 国产一区二区三区在线看 | 国产黄在线 | 成人在线不卡 | 综合色在线 | 亚洲区在线| 日韩av在线免费播放 | 国产乱国产乱300精品 | 中文字幕黄色片 | 午夜88| 国产精品2区 | 日产av在线 | 中文字幕免费在线观看 | 一级片在线免费观看 | 天天爽天天 | 亚洲激情另类 | 久草网在线观看 | 久久久国产精品视频 | 波多野结衣一区二区 | 欧美日本精品 | 91精品久久久久久 | 夜夜嗨av一区二区三区 | 免费三片在线观看网站v888 | 亚洲在线一区 | 日韩一级在线观看 | 日韩视频在线免费观看 | 欧美性视频在线 | 国产亚洲精品码 | 能看毛片的网站 | 免费理论片| 精品在线一区 | 色综合一区 | 国产ts在线 | 欧美视频一区二区三区 | 精品国产91 | 天天爱综合 | 国产无精乱码一区二区三区 | 韩日精品视频 | 日韩一区二区三区在线播放 | 欧美日韩国产一区二区 |