通过调用 new proxy()你可以创建一个代理来替代另一个对象(被称为目标), 这个代理对目标对象进行了虚拟, 因此该代理与该目标对象表面上可以被当做同一个对象来对待.
创建一个简单的代理
当你使用 Proxy 构造器来创建一个代理时, 需要传递两个参数: 目标对象以及一个处理器, 后者是定义了一个或多个陷阱函数的对象. 如果未提供陷阱函数, 代理会对所有操作采取默认行为.
使用 set 陷阱函数验证属性值
- let target = {};
- var proxy = new Proxy(target, {
- set(trapTarget, key, value, receiver) {
- if (!trapTarget.hasOwnProperty(key)) {
- if (isNaN(value)) {
- throw new Error('Proxy must be a number');
- }
- }
- return Reflect.set(trapTarget, key, value, receiver);
- }
- })
- proxy.count = 1;
- console.log(proxy.count);
- console.log(target.count);
- try {
- proxy.anthorName = 'cc';
- } catch (err) {
- console.log(err.message);
- }
使用上述方法可以对添加给对象的属性值进行验证, 如果值为非数字, 就会抛出错误.
使用 get 陷阱函数进行对象外形验证
在 JS 中, 如果读取一个对象中不存在的属性时, 会显示 undefined, 这对于排查问题很不利. 使用代理进行对象外形验证就可以帮你从这个错误中拯救出来.
- let proxy = new Proxy({}, {
- get(trapTarget, key, receiver) {
- if (!(key in receiver)) {
- throw new Error(`property ${key} not exist`);
- }
- return Reflect.get(trapTarget, key, receiver);
- }
- })
- proxy.name = 'cc';
- try {
- console.log(proxy.age);
- } catch (error) {
- console.log(error.message);
- }
- // 输出结果
- property age not exist
上述代码对打印的对象属性进行验证, 如果不存在则抛出一个错误. 今日头条的一个面试题
使用 has 陷阱函数隐藏属性
in 运算符用于判断指定对象中是否存在某个属性, 如果对象的属性名与指定的字符串或符号值相匹配, 那么 in 运算符应当返回 true, 无论该属性是对象自身的属性还是原型的属性. 代理允许你使用 has 陷阱函数来解决这个问题
has 陷阱函数会在使用 in 运算符的情况下被调用, 并且会被传入两个参数:
trapTarget: 需要读取属性的对象(即代理的目标对象)
key: 需要检查的属性的键 (字符串类型或符号类型)Reflect.has() 方法接收与之相同的参数并向 in 运算符返回默认相应结果
- let target = {
- name: 'cc',
- age: 26,
- sex: 'man'
- }
- let proxy = new Proxy(target, {
- has(trapTarget, key) {
- if (trapTarget.hasOwnProperty(key)) {
- return Reflect.has(trapTarget, key);
- } else {
- return false;
- }
- }
- })
- console.log('toString' in proxy);
- console.log('name' in proxy);
- console.log('age' in proxy);
使用 deleteProperty 陷阱函数避免属性被删除
delete 运算符能从指定对象上删除一个属性, 在删除成功时返回 true, 否则返回 false
deleteProperty 陷阱函数会在使用 delete 运算符去删除对象属性时被调用, 并且会被传入两个参数:
trapTarget: 需要删除属性的对象
key: 需要删除的属性的键
Reflect.deleteProperty()方法也接受两个参数, 并提供了 deleteProperty 陷阱函数的默认实现.
- let target = {
- name: 'target',
- value: 42
- }
- let proxy = new Proxy(target, {
- deleteProperty(trapTarg, ke) {
- if (ke === 'value') {
- return false;
- } else {
- return Reflect.deleteProperty(trapTarg, ke);
- }
- }
- })
- let result = delete proxy.value;
- let result1 = delete proxy.name;
- console.log(result);
- console.log(result1);
来源: https://www.cnblogs.com/xzsty/p/11357820.html