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

您的位置:首頁技術文章
文章詳情頁

理解JavaScript中的Proxy 與 Reflection API

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

一、創建 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 構造器創建的 proxy 對象會將自身的所有操作直接轉發給 target。當 proxy.name 被賦值為 'proxy' 時,target 對象也會創建 name 屬性并獲得同樣的值。實際上 proxy 對象本身并不創建和存儲 name 屬性,它只是轉發對應的操作給 target。

類似的,proxy.name 與 target.name 的值始終保持一致,因為它們實際上都指向了 target.name。這也意味著給 target.name 賦予一個新的值時,該變化也會反映到 proxy.name 上。

使用 set Trap 驗證屬性

Proxy 允許開發者主動攔截本該轉發給 target 對象的底層操作,這些攔截行為通過 trap 實現。每個 trap 都可以覆蓋 JavaScript 對象的某些內置行為,即 proxy 允許通過 trap 攔截并修改指向 target 對象的操作。

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

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 中的四個參數含義如下:

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

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

使用 get Trap 令程序讀取不存在屬性時報錯

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

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

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

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 的現實應用

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的詳細內容,更多關于JavaScript中的Proxy 與 Reflection API的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 成人午夜精品久久不卡 | 免费区欧美一级毛片精品 | 视频一区视频二区在线观看 | 人成精品视频三区二区一区 | 成视频年人黄网站免费 | 欧美一级大黄特黄毛片视频 | 久草视频免费在线观看 | 国产又色又爽黄的网站免费 | 456亚洲视频 | 特级毛片在线播放 | 特级毛片在线播放 | 国产精品亚洲精品日韩已满 | 欧美大屁股精品毛片视频 | 国产欧美综合一区二区 | 国产理论在线观看 | 久草勉费视频 | 巨乳女上司 | 欧美黑大粗硬毛片视频 | 欧美日韩中文一区二区三区 | 久久精品视频免费播放 | 一级做a免费视频观看网站 一级做a爰 | 精品韩国主播福利视频在线观看一 | 日韩a级片| 亚色成人| 欧美高清videossex19 | 私人毛片免费高清影视院丶 | 欧美日韩国产成人精品 | 久久亚洲私人国产精品va | 香蕉久久夜色精品国产 | 国内精品99| 国产一区在线播放 | 国产日韩欧美精品一区二区三区 | 午夜国产精品不卡在线观看 | 国产在线观看精品 | 国内精品小视频在线 | 亚洲精品视频久久 | 亚洲一区成人 | 欧美成人区 | 天天躁天天碰天天看 | 国产三级做爰高清在线 | 日本三级香港三级少妇 |