网站开发运作,烟台汽车网站建设,网站运营指标,环球资源网发展现状JavaScript 在 ES6 中#xff0c;引入了一个新的对象类型 Proxy#xff0c;它可以用来代理另一个对象#xff0c;并可以在代理过程中拦截、覆盖和定制对象的操作。Proxy 对象封装另一个对象并充当中间人#xff0c;其提供了一个捕捉器函数#xff0c;可以在代理对象上拦截…
JavaScript 在 ES6 中引入了一个新的对象类型 Proxy它可以用来代理另一个对象并可以在代理过程中拦截、覆盖和定制对象的操作。Proxy 对象封装另一个对象并充当中间人其提供了一个捕捉器函数可以在代理对象上拦截所有的操作包括访问属性、赋值属性、函数调用等等。通过拦截这些操作可以对代理对象进行定制和控制。 在开始介绍 Proxy 对象前先了解 3 个术语
target 目标对象要代理的对象或函数。handler 处理程序对代理的对象或函数执行某些操作的函数。traps 捕捉器这些是一些用于处理目标的函数。单击此处阅读有关陷阱的更多信息。
语法
Proxy 对象的基本语法如下
new Proxy(target, handler);其中target 是被代理的目标对象handler 是一个对象它包含了一些捕捉器函数用来拦截代理对象的操作。
下面是一些常见的拦截操作和对应的捕捉器函数
对象方法
getPrototypeOf()Object.getPrototypeOf 方法的捕捉器。setPrototypeOf()Object.setPrototypeOf 方法的捕捉器。isExtensible()Object.isExtensible 方法的捕捉器。preventExtensions()Object.preventExtensions 方法的捕捉器。getOwnPropertyDescriptor()Object.getOwnPropertyDescriptor 方法的捕捉器。handler.defineProperty()Object.defineProperty 方法的捕捉器。
属性获取器/设置器
get(target, propKey, receiver)拦截对象的读取属性操作返回属性值。set(target, propKey, value, receiver)拦截对象的设置属性操作返回一个布尔值表示是否设置成功。has(target, propKey)拦截对象的 in 操作符返回一个布尔值表示对象是否包含该属性。deleteProperty(target, propKey)拦截对象的 delete 操作符返回一个布尔值表示是否删除成功。ownKeys()Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器
函数方法
如果目标对象是一个函数可以使用下面 2 个捕捉器。
apply(target, thisArg, args)拦截函数的调用操作返回调用结果。construct(target, args, newTarget)拦截 new 操作符返回一个对象。
Proxy 在目标对象周围创建一个不可检测的屏障将所有操作重定向到处理程序对象。如果发送一个空的 handler 代理只是原始对象的一个空包装器。
const author {name: Quintion,age: 36,
};const proxyAuthor new Proxy(author, {});console.log(author.name); // Quintion
console.log(proxyAuthor.name); // Quintion为了赋予代理意义需要向处理程序添加一些操作方法。
捕捉器
每当与一个对象交互时都在调用一个内部方法。代理允许使用捕捉器拦截给定内部方法的执行。
因此当运行 author.name 时告诉 JavaScript 引擎调用内部 [[GET]] 方法来检索 name 属性。当运行 proxyAuthor.name 时get 捕捉器会调用处理程序中定义的 get() 函数来执行然后再将调用发送到原始对象。 get
get() 方法有两个必需的参数
target — 传递给代理的对象。property — 访问的属性的名称。
要自定义代理在处理程序对象上定义函数。下面定义了 get 方法来记录访问
const handler {get(target, property) {console.log(捕捉器 GET:${property});return target[property];},
};为了让调用通过捕捉器 get 返回 target[property]。使用方式如下
const author {name: Quintion,age: 36,
};const handler {get(target, property) {console.log(捕捉器 GET[${property}]);return target[property];},
};const proxyAuthor new Proxy(author, handler);console.log(proxyAuthor.name);执行后将打印以下内容
捕捉器 GET[name]
Quintionset
set 捕捉器用于给目标对象进行赋值操作返回值是一个布尔值。set 捕捉器需要的参数如下
target — 传递给代理的对象。property — 将被设置的属性名或 Symbol。value — 新的属性值receiver — 最初被调用的对象。
下面通过 set 捕捉器验证年龄值的输入
const handler {set(target, property, value) {if (property age typeof value ! number) {throw new TypeError(年龄必须是一个数字);}target[property] value;return true;},
};下面尝试将错误的类型值赋值给 age 则会抛出错误
const proxyAuthor new Proxy(author, handler);proxyAuthor.age young;
// 执行后抛出异常throw new TypeError(年龄必须是一个数字);set() 方法应该返回一个布尔值 true 用来表示赋值成功。 在严格模式下运行并且返回一个假值或什么都不返回则会抛出错误。 除了拦截对属性的读取和修改Proxy 总共可以拦截 13 种操作。
应用场景
通过 Proxy 对象的特征可以将其使用在下面这些场合
验证和过滤
代理Proxy 用于拦截和验证对对象属性的访问。如可以创建一个代理来检查用户输入的数据是否符合预期的格式并拒绝不正确的数据。就如下面 age 属性赋值判断
缓存
代理Proxy 用于缓存对象的操作结果以避免重复计算。如可以创建一个代理来拦截对象的某些方法并将结果存储在缓存中以便将来使用。
下面是一个基于 Proxy 的缓存库的示例
class Cache {constructor() {this.cache new Map();this.proxy new Proxy(this, {get(target, property) {if (property get) {return (key) {return target.cache.get(key);};}if (property set) {return (key, value) {target.cache.set(key, value);};}if (property has) {return (key) {return target.cache.has(key);};}if (property delete) {return (key) {return target.cache.delete(key);};}},});}
}在上面的代码中定义了一个 Cache 类该类中包含一个内部的 Map 对象用于存储缓存数据并且定义了一个 proxy 对象作为该类的代理。
在 proxy 对象的 get 方法中根据传入的属性名返回相应的方法。如果属性名为 get则返回一个可以获取缓存值的方法如果属性名为 set则返回一个可以设置缓存值的方法如果属性名为 has则返回一个可以判断是否存在缓存值的方法如果属性名为 delete则返回一个可以删除缓存值的方法。
下面是一个使用该缓存库的示例
const cacheHelper new Cache();cacheHelper.set(foo, bar);
console.log(cacheHelper.get(foo)); // bar
console.log(cacheHelper.has(foo)); // truecacheHelper.delete(foo);
console.log(cacheHelper.get(foo)); // undefined
console.log(cacheHelper.has(foo)); // false在上面的代码中创建了一个 Cache 对象并调用其 set 方法设置缓存值然后调用其 get 方法获取缓存值并调用其 has 方法判断缓存值是否存在最后调用其 delete 方法删除缓存值。
监听属性变化
代理Proxy用于监视对象属性的变化并在属性发生变化时触发其他操作。如创建一个代理来监视对象属性的变化并在属性发生变化时更新页面上的元素。
防止误操作
代理Proxy用于防止误操作如创建一个代理来拦截对象的某些方法并在方法调用时检查一些条件以确保方法只在正确的上下文中调用。
虚拟化
代理Proxy可以用于创建虚拟化对象。如创建一个代理对象用于代替某个对象的真实实现并且在实际对象执行之前对其进行修改或拦截。
总结
上面介绍了如何使用代理Proxy对象来监视对象通过使用处理程序对象中的捕捉器方法向它们添加自定义行为提供更高级的对象操作和控制功能从而增强代码的可读性和可维护性。