时间:2021-05-18
一、创建 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 中的四个参数含义如下:
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:///books/secrets-of-the-javascript-ninja-second-edition
以上就是理解JavaScript中的Proxy 与 Reflection API的详细内容,更多关于JavaScript中的Proxy 与 Reflection API的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
概述Proxy与Reflect是ES6为了操作对象引入的API。Proxy可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是
本文实例讲述了ES6中Proxy与Reflect实现重载(overload)的方法。分享给大家供大家参考,具体如下:Proxy与Reflect实现重载(over
JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性。主要内容如下:理解JavaScript
前面的话本文将详细介绍SVG基本操作API,并使用这些API制作实例效果基础API在javascript中,可以使用一些基本的API来对SVG进行操作【NS地址
本文实例讲述了javascript设计模式–代理模式原理与用法。分享给大家供大家参考,具体如下:介绍:代理使我们很常见的一众模式,proxy,nginx都称之为