色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁(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大一片 | 久久无码av三级 | 日本精品久久久久久久 | 国内三级视频 | 国产情侣无套精品视频 | 91精品在线免费 | 久久中文字幕在线观看 | 视频偷拍一级视频在线观看 | 欧美一级特黄一片免费 | 99久久免费精品视频 | 97视频免费观看 | 国产亚洲精品自在久久77 | 99久久伊人一区二区yy5o99 | 国模午夜写真福利视频在线 | 久久欧美精品欧美九久欧美 | 国产精品99| 亚洲精品视频久久久 | 一级片www | 国产成人久久久精品毛片 | 婷婷久久久五月综合色 | 国产美女动态免费视频 | 国产午夜精品免费一二区 | 久久久精品国产 | 色在线看 | 欧美一级特黄特黄做受 | 国产一区二区三区在线看 | 日本免费久久 | 美女被爆免费视频软件 | 亚州一级片 | 午夜伊人| 国产在线91精品天天更新 | 欧美性色生活片免费播放 | 亚洲国产伦理 | 一级黄片一级毛片 | 中美日韩在线网免费毛片视频 | 在线播放成人高清免费视频 | 特黄特色大片免费播放路01 | 国产亚洲精品自在久久77 | 国产精品精品国产一区二区 |