午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

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

理解JavaScript中的Proxy 與 Reflection API

瀏覽:145日期: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。

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

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

Proxy 允許開(kāi)發(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ù)字類(lèi)型的對(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)文章:
主站蜘蛛池模板: 人人澡人人看 | 亚洲欧美另类视频 | 九九热在线视频观看 | 午夜精品三级久久久有码 | www97| 亚洲一区二区av在线 | 亚洲欧洲在线观看 | 亚洲视频一区二区在线观看 | 日本高清视频一区二区 | 成年人网站免费在线观看 | 久久天堂网 | 久久国产小视频 | 欧美亚洲在线 | 毛片毛片毛片毛片毛片毛片毛片 | 亚洲网站免费观看 | 精品伊人久久 | 四虎成人影视 | 久久只有这里有精品 | 一区在线观看 | 日本成人在线视频网站 | 亚洲免费观看视频 | 美女久久精品 | 丁香午夜| 色999视频| 91青青视频| 999在线视频 | 亚洲激情视频在线观看 | 日韩亚洲天堂 | 日韩欧美高清 | 欧美激情精品久久 | 美女激情啪啪 | 欧美大胆a | 黄色三级国产 | 日韩高清一级 | 久久午夜片 | 久久久精品久久久 | 97色在线视频 | 亚洲成人精品一区二区三区 | 手机在线观看av | 97色碰| 亚洲一二三视频 |