国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

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

理解JavaScript中的Proxy 與 Reflection API

瀏覽:95日期: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' 時(shí),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 賦予一個(gè)新的值時(shí),該變化也會反映到 proxy.name 上。

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

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

假設(shè)需要創(chuàng)建一個(gè)新添加的屬性值只能是數(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 中的四個(gè)參數(shù)含義如下:

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

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

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

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

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

可以借助 get trap 修改讀取對象屬性時(shí)的默認(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)文章:
主站蜘蛛池模板: 免费视频久久 | jk制服福利在线播放 | av毛片在线看 | 日本欧美一级aaaaa毛片 | 日韩在线一区二区三区免费视频 | 精品91精品91精品国产片 | 国产在线精品观看一区 | 俄罗斯aaaa一级毛片 | 国产成人精品曰本亚洲77美色 | 美女被靠视频免费网站不需要会员 | 日本在线看小视频网址 | 久久99亚洲精品久久久久网站 | 经典香港a毛片免费观看 | 久草在线免费福利视频 | a级男女性高爱潮高清试 | 亚洲欧洲无码一区二区三区 | 国产一级性片 | 亚洲精品天堂一区在线观看 | 国产美女毛片 | 国内精品久久久久影院不卡 | 欧美另类极品 | 天天综合天天看夜夜添狠狠玩 | 久久99热精品免费观看k影院 | 欧美一级欧美一级在线播放 | 欧美一区二区在线免费观看 | 亚洲精品不卡在线 | 99国产高清久久久久久网站 | 天天五月天丁香婷婷深爱综合 | 国产人成 | 日韩精品免费一区二区三区 | 91精品欧美一区二区三区 | 欧美级 | 亚洲美女视频一区二区三区 | 日韩欧美一区二区在线 | 一级成人黄色片 | 欧美成人精品大片免费流量 | 日韩高清在线播放不卡 | 亚洲国产第一区二区香蕉日日 | 日本68xxxxxxxxx老师| 久草亚洲视频 | 久久精品免费视频观看 |