欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

理解JavaScript中的Proxy 與 Reflection API

 更新時(shí)間:2020年09月21日 11:55:21   作者:Starryland  
這篇文章主要介紹了JavaScript中的Proxy 與 Reflection API的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下

一、創(chuàng)建 Proxy

let target = {}
let proxy = new Proxy(target, {})

proxy.name = "proxy"
console.log(proxy.name)  // proxy
console.log(target.name) // proxy

target.name = "target"
console.log(proxy.name)  // target
console.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 = 1
console.log(proxy.count)  // 1
console.log(target.count) // 1

proxy.name = "proxy"
console.log(proxy.name)  // proxy
console.log(target.name)  // proxy

proxy.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) // proxy

console.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)  // true

let result1 = delete target.value
console.log(result1)       // true
console.log("value" in target)  // false

let result2 = delete target.name
console.log(result2)       // false
console.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)  // true

let result1 = delete proxy.value
console.log(result1)       // false
console.log("value" in proxy)  // true

let result2 = delete proxy.name
console.log(result2)       // true
console.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 firstNinjaDir
console.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)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 自定義排序算法在JavaScript中的應(yīng)用小結(jié)

    自定義排序算法在JavaScript中的應(yīng)用小結(jié)

    這篇文章主要介紹了自定義排序算法在JavaScript中的應(yīng)用,通過(guò)自定義排序函數(shù),我們能夠精確控制數(shù)組元素的排序邏輯,從而滿足各種復(fù)雜的應(yīng)用場(chǎng)景,需要的朋友可以參考下
    2024-12-12
  • 用RadioButten或CheckBox實(shí)現(xiàn)div的顯示與隱藏

    用RadioButten或CheckBox實(shí)現(xiàn)div的顯示與隱藏

    用RadioButten(或CheckBox)實(shí)現(xiàn)div的顯示與隱藏,當(dāng)選擇“女”時(shí),顯示“美女、才女”;當(dāng)選擇“男”時(shí)隱藏,具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下
    2013-09-09
  • QML實(shí)現(xiàn)圓環(huán)顏色選擇器

    QML實(shí)現(xiàn)圓環(huán)顏色選擇器

    這篇文章主要為大家詳細(xì)介紹了QML實(shí)現(xiàn)圓環(huán)顏色選擇器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 使用script的src實(shí)現(xiàn)跨域和類似ajax效果

    使用script的src實(shí)現(xiàn)跨域和類似ajax效果

    在解決js的跨域問(wèn)題的時(shí)候, 有多種方式, 其中有一種是利用script標(biāo)簽的src屬性,因?yàn)檫@個(gè)屬性是不受域名限制的,我們可以直接讓src的這個(gè)鏈接指向跨域網(wǎng)站的一個(gè)接口, 這個(gè)接口返回的是js代碼或者json格式數(shù)據(jù), 從而實(shí)現(xiàn)跨域獲取數(shù)據(jù)。
    2014-11-11
  • JavaScript中DOM和BOM原理詳析

    JavaScript中DOM和BOM原理詳析

    這篇文章主要介紹了JavaScript中DOM和BOM原理詳析,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • 基于Cesium實(shí)現(xiàn)衛(wèi)星在軌繞行動(dòng)畫

    基于Cesium實(shí)現(xiàn)衛(wèi)星在軌繞行動(dòng)畫

    這篇文章主要為大家詳細(xì)介紹了如何利用Cesium實(shí)現(xiàn)衛(wèi)星在軌繞行動(dòng)畫,文中的示例代碼講解詳細(xì),對(duì)我們了解Cesium有一定的幫助,感興趣的可以嘗試一下
    2022-06-06
  • 封裝一個(gè)公用Echarts圖表組件的3種模板代碼示例

    封裝一個(gè)公用Echarts圖表組件的3種模板代碼示例

    這篇文章主要給大家介紹了關(guān)于封裝一個(gè)公用Echarts圖表組件的3種模板,定義圖表公共樣式是為了統(tǒng)一同一網(wǎng)站各頁(yè)面圖表的基礎(chǔ)樣式,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • 通過(guò)JS判斷聯(lián)網(wǎng)類型和連接狀態(tài)的實(shí)現(xiàn)代碼

    通過(guò)JS判斷聯(lián)網(wǎng)類型和連接狀態(tài)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了通過(guò)JS判斷聯(lián)網(wǎng)類型和連接狀態(tài)的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04
  • JavaScript Window瀏覽器對(duì)象模型原理解析

    JavaScript Window瀏覽器對(duì)象模型原理解析

    這篇文章主要介紹了JavaScript Window瀏覽器對(duì)象模型,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • JS實(shí)現(xiàn)小星星特效

    JS實(shí)現(xiàn)小星星特效

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)小星星特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12

最新評(píng)論