什么是 Proxy 代理对象?
Proxy 代理对象是 ES6 中的一个新特性,它可以用来代理另一个对象,可以拦截并改变这个对象的底层操作。Proxy 对象是用于创建一个对象的代理,它可以拦截并重载 JavaScript 中的一些操作,例如属性访问、函数调用、构造函数调用等。
Proxy 对象的语法
创建一个 Proxy 对象需要使用 new Proxy()
方法,该方法接收两个参数,分别是需要代理的目标对象和一个处理程序对象(也称为拦截器对象)。
// javascriptcn.com 代码示例 let target = {}; let handler = { get: function(target, prop, receiver) { console.log(`Getting ${prop}`); return Reflect.get(target, prop, receiver); }, set: function(target, prop, value, receiver) { console.log(`Setting ${prop} to ${value}`); return Reflect.set(target, prop, value, receiver); } }; let proxy = new Proxy(target, handler);
上面的代码中,我们创建了一个空对象 target
,然后创建了一个处理程序对象 handler
,该对象中包含了两个拦截器函数 get
和 set
,这两个函数可以拦截对象的属性获取和设置操作。最后,我们使用 new Proxy()
方法创建了一个代理对象 proxy
,该对象代理了目标对象 target
。
Proxy 对象的拦截器函数
get 拦截器
get
拦截器可以拦截对象属性的读取操作。当我们读取代理对象的属性时,get
拦截器会被触发,我们可以在这个函数中对属性读取操作进行拦截和修改。
// javascriptcn.com 代码示例 let target = { name: 'Tom', age: 18 }; let handler = { get: function(target, prop, receiver) { console.log(`Getting ${prop}`); return Reflect.get(target, prop, receiver); } }; let proxy = new Proxy(target, handler); console.log(proxy.name); // Getting name Tom console.log(proxy.age); // Getting age 18
上面的代码中,我们使用 get
拦截器拦截了代理对象的属性读取操作,并打印了被读取的属性名和属性值。
set 拦截器
set
拦截器可以拦截对象属性的设置操作。当我们设置代理对象的属性时,set
拦截器会被触发,我们可以在这个函数中对属性设置操作进行拦截和修改。
// javascriptcn.com 代码示例 let target = { name: 'Tom', age: 18 }; let handler = { set: function(target, prop, value, receiver) { console.log(`Setting ${prop} to ${value}`); return Reflect.set(target, prop, value, receiver); } }; let proxy = new Proxy(target, handler); proxy.age = 20; // Setting age to 20 console.log(proxy.age); // 20
上面的代码中,我们使用 set
拦截器拦截了代理对象的属性设置操作,并打印了被设置的属性名和属性值。
apply 拦截器
apply
拦截器可以拦截函数调用操作。当我们调用代理对象的方法时,apply
拦截器会被触发,我们可以在这个函数中对函数调用操作进行拦截和修改。
// javascriptcn.com 代码示例 let target = function(x, y) { return x + y }; let handler = { apply: function(target, thisArg, args) { console.log(`Calling ${target.name} with args ${args}`); return Reflect.apply(target, thisArg, args); } }; let proxy = new Proxy(target, handler); console.log(proxy(1, 2)); // Calling anonymous with args 1,2 3
上面的代码中,我们使用 apply
拦截器拦截了代理对象的函数调用操作,并打印了被调用的函数名和参数。
construct 拦截器
construct
拦截器可以拦截构造函数的调用操作。当我们使用 new
关键字创建代理对象时,construct
拦截器会被触发,我们可以在这个函数中对构造函数调用操作进行拦截和修改。
// javascriptcn.com 代码示例 let target = function(name, age) { this.name = name; this.age = age; }; let handler = { construct: function(target, args) { console.log(`Constructing ${target.name} with args ${args}`); return Reflect.construct(target, args); } }; let proxy = new Proxy(target, handler); let obj = new proxy('Tom', 18); // Constructing anonymous with args Tom,18 console.log(obj); // { name: 'Tom', age: 18 }
上面的代码中,我们使用 construct
拦截器拦截了代理对象的构造函数调用操作,并打印了被调用的构造函数名和参数。
Proxy 对象的应用场景
数据验证和过滤
我们可以使用 set
拦截器来对对象属性设置操作进行验证和过滤。
// javascriptcn.com 代码示例 let target = {}; let handler = { set: function(target, prop, value, receiver) { if (typeof value !== 'number') { console.log(`Invalid value: ${value}`); return false; } return Reflect.set(target, prop, value, receiver); } }; let proxy = new Proxy(target, handler); proxy.age = 18; // 18 proxy.age = '18'; // Invalid value: 18
上面的代码中,我们使用 set
拦截器对代理对象的属性设置操作进行了验证,当设置的属性值不是数字时,会打印一条错误信息,并返回 false
。
数据缓存
我们可以使用 get
拦截器来对对象属性读取操作进行缓存。
// javascriptcn.com 代码示例 let target = { name: 'Tom', age: 18 }; let handler = { get: function(target, prop, receiver) { if (prop === 'fullName') { console.log(`Calculating fullName`); return `${target.name}(${target.age})`; } return Reflect.get(target, prop, receiver); } }; let proxy = new Proxy(target, handler); console.log(proxy.fullName); // Calculating fullName Tom(18) console.log(proxy.fullName); // Tom(18)
上面的代码中,我们使用 get
拦截器对代理对象的属性读取操作进行了缓存,当读取 fullName
属性时,会计算出一个新的属性值,并将其缓存起来,下次再读取 fullName
属性时,就直接返回缓存的值。
数据绑定
我们可以使用 set
和 get
拦截器来实现数据绑定。
// javascriptcn.com 代码示例 let target = { name: 'Tom', age: 18 }; let handler = { get: function(target, prop, receiver) { console.log(`Getting ${prop}`); return Reflect.get(target, prop, receiver); }, set: function(target, prop, value, receiver) { console.log(`Setting ${prop} to ${value}`); let result = Reflect.set(target, prop, value, receiver); console.log(`Triggering change event`); return result; } }; let proxy = new Proxy(target, handler); proxy.name = 'Jerry'; // Setting name to Jerry Triggering change event
上面的代码中,我们使用 set
和 get
拦截器来实现数据绑定,当设置代理对象的属性时,会触发 set
拦截器,我们可以在这个函数中触发一个事件,通知其他模块数据已经发生了变化;当读取代理对象的属性时,会触发 get
拦截器,我们可以在这个函数中对属性读取操作进行拦截和修改,例如自动添加前缀或后缀等。
总结
Proxy 代理对象是 ES6 中的一个新特性,它可以用来代理另一个对象,可以拦截并改变这个对象的底层操作。Proxy 对象是用于创建一个对象的代理,它可以拦截并重载 JavaScript 中的一些操作,例如属性访问、函数调用、构造函数调用等。我们可以使用 Proxy 对象来实现数据验证和过滤、数据缓存、数据绑定等功能。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6558a695d2f5e1655d2d3c2d