成人视屏在线观看-国产99精品-国产精品1区2区-欧美一级在线观看-国产一区二区日韩-色九九九

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

理解JavaScript中的Proxy 與 Reflection API

瀏覽:97日期: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 對(duì)象會(huì)將自身的所有操作直接轉(zhuǎn)發(fā)給 target。當(dāng) proxy.name 被賦值為 'proxy' 時(shí),target 對(duì)象也會(huì)創(chuàng)建 name 屬性并獲得同樣的值。實(shí)際上 proxy 對(duì)象本身并不創(chuàng)建和存儲(chǔ) name 屬性,它只是轉(zhuǎn)發(fā)對(duì)應(yīng)的操作給 target。

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

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

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

假設(shè)需要?jiǎng)?chuàng)建一個(gè)新添加的屬性值只能是數(shù)字類型的對(duì)象,就可以借助 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:接收新屬性的對(duì)象(即 proxy 指向的 target) key:新屬性對(duì)應(yīng)的 key value:新屬性對(duì)應(yīng)的 value receiver:通常為 proxy 自身

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

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

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

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

可以借助 get trap 修改讀取對(duì)象屬性時(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.

通過(guò) deleteProperty Trap 防止刪除屬性

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

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

性能測(cè)試

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

自動(dòng)添加屬性

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的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品视频免费看 | 欧美日韩在线播放一区二区三区 | 久久精品国内偷自一区 | 久久久免费观看视频 | 欧美一线高本道高清在线 | 国内自产拍自a免费毛片 | 日本国产免费一区不卡在线 | 成人性生片全套 | 成人免费xxxxx在线视频 | 久青草免费在线视频 | 欧美亚洲中日韩中文字幕在线 | 亚洲欧美日本综合一区二区三区 | 美女个护士一级毛片亚洲 | 亚洲羞羞视频 | 中文字幕一二区 | 国内精品久久久久久影院老狼 | 女性无套免费网站在线看 | 韩国日本一级毛片免费视频 | 久久成人免费网站 | 国产亚洲欧美一区二区三区 | 亚洲在线观看视频 | 国产特级全黄一级毛片不卡 | 午夜伊人网 | 欧美精品在欧美一区二区 | 香蕉97碰碰视频免费 | 国产主播福利精品一区二区 | 一区二区三区精品国产 | 怡红院宜春院 | 久久国产精品久久国产片 | 亚洲高清中文字幕一区二区三区 | 国产亚洲高清在线精品不卡 | 亚洲一区免费视频 | 成人国产综合 | 一级做性色a爰片久久毛片免费 | 国产精品久久久久国产精品 | 国产成人亚洲精品一区二区在线看 | 性欧美另类老妇高清 | 免费亚洲黄色 | 日本手机在线视频 | 一级一片免费播放 | 91欧洲在线视精品在亚洲 |