Proxy 代理 ,在我们访问对象前添加了一层拦截,可以过滤很多操作
let a = new Proxy(target, handler);
target
: 需要包装的对象,可以是数组、函数、class类、Proxy等handler
: 传入一个对象,对target
进行的具体操作
以Proxy的get示例
get
let obj = {
val: 'aaa'
}
let proxyObj = new Proxy(obj,{
get(target, key) {
return target[key] + '我被代理过了'
}
})
console.log(proxyObj.val)
// aaa我被代理过了
创建一个obj,然后对其属性进行get监听,obj成为了proxyObj的实例,访问obj属性时,需要写proxyObj.xxx 这样就会被proxy拦截
get可以对所有属性进行拦截,无论是已创建的还是未创建的
// 接上一个例子
...
obj.b = 'bbb'
console.log(proxyObj.b)
// bbb我被代理过了
proxyObj.c
// undefined我被代理过了
proxyObj.c = 'ccc'
console.log(proxyObj.c)
// ccc我被代理过了
从上例中可以看出,无论是在obj中新赋值的属性,还是proxyObj中新赋值的属性,都可以被get监听到
set
const obj = {};
const a = new Proxy(obj, {
set(target, prop, value){
target[prop] = value + '我被代理过了';
// return true;
}
})
a.a = 'aaa';
// aaa
console.log(a.a)
// aaa我被代理过了
set可以监听目标对象的所有属性赋值行为。如果目标对象自身的某个属性是不可写也不可配置的,那么 set 不得改变这个属性的值,只能返回同样的值,否则报错。
apply
apply可以监听调用时的行为
var fun = function (a,b) {
return a + b
}
var a = new Proxy(fun, {
apply(target, thisArg, args) {
console.log('target', target)
console.log('thisArg', thisArg)
console.log('args', args)
return target.call(thisArg, ...args)
}
})
a(1,2)
// 'target' ƒ (a,b) { return a + b }
// 'thisArg' undefined
// 'args' [1, 2]
// 3
window.a(1,2)
// 'target' ƒ (a,b) { return a + b }
// 'thisArg' window {...}
// 'args' [1, 2]
// 3
apply中的参数
target
原始的函数thisArg
调用时指向的this对象args
调用时取得的形参
construct
construct
可以监听目标对象在new时的执行
class a {}
var c = new Proxy(a, {
construct(target, args, newTarget) {
console.log('target', target)
console.log('args', args)
console.log('newTarget', newTarget)
return {args: args}
}
})
new c(1,2,3)
// target class a {}
// args [1, 2, 3]
// newTarget Proxy {length: 0, prototype: {…}, name: "a"}
// {args: Array(3)}
construct中的参数和返回值
target
原始的class类args
调用时取得的形参newTarget
new target所得return
返回new所得到的实例
Proxy的其他属性
图片引自PHP中文网的不言大神的博客
get、set监听时,Proxy和Object.definePrototype的区别
Object.defineProperty
- 只能劫持对象的属性,如果属性也是对象需要深度便利
- 对数组监听,无法监听到他的变化
- 只能对对象中的单个属性监听
- 除了get、set,还有configurable、enumerable、value
Proxy
- Proxy需要创建一个新对象,监听后所有的操作需要在新对象上执行
- 会监听到对象中所有属性(可读写的)
- 除了get、set,还有apply、construct等很多属性