前端小白成长05--Proxy
2020-05-17 本文已影响0人
Clover园
JavaScript中的Proxy
翻译过来就是代理的意思,Proxy是ES6中提供的新的API,可以用来定义对象各种基本操作的自定义行为 (在文档中被称为traps),拿它可以做很多有意思的事情,在我们需要对一些对象的行为进行控制时将变得非常有效。
Proxy的语法
创建一个Proxy的实例需要传入两个参数
1.target 要被代理的对象,可以是一个object或者function
2.handlers对该代理对象的各种操作行为处理,可以称为处理对象
defineProperty和proxy区别
- defineProperty只能监视属性的读写
- proxy能监视更多的对象操作 ,比如属性的调用,方法的调用,属性的删除等等
class Test {
constructor (a, b) {
console.log('constructor', a, b)
}
}
// Test(1, 2) // throw an error
let proxyClass = new Proxy(Test, {apply (target, thisArg, argumentsList) {
// 如果想要禁止使用非new的方式来调用函数,直接抛出异常即可
// throw new Error(`Function ${target.name} cannot be invoked without 'new'`)
return new (target.bind(thisArg, ...argumentsList))()
}
})
proxyClass(1, 2) // constructor 1 2
我们使用了apply来代理一些行为,在函数调用时会被触发,因为我们明确的知道,代理的是一个Class或构造函数,所以我们直接在apply中使用new关键字来调用被代理的函数。
以及如果我们想要对函数进行限制,禁止使用new关键字来调用,可以用另一个trap:construct
function add (a, b) {
return a + b
}
let proxy = new Proxy(add, {
construct (target, argumentsList, newTarget) {
throw new Error(`Function ${target.name} cannot be invoked with 'new'`)
}
})
proxy(1, 2) // 3
new proxy(1, 2) // throw an erro
还有一些对象的方法
- proxy 更好的支持数组对象的监视
最长用的也是vue用的,重写数组的操作方法
数组对象的操作
Proxy是非侵入的方法监管了对象的读写
const observe = (data, callback) => {
return new Proxy(data, {
get(target, key) {
console.log('get:',target, key)
return Reflect.get(target, key)
},
set(target, key, value, proxy) {
console.log('set:',target, key,value,proxy)
callback(key, value);
target[key] = value;
return Reflect.set(target, key, value, proxy)
}
})
}
const FooBar = { open: false,num:123 };
const FooBarObserver = observe(FooBar, (property, value) => {
console.log(property, value)// callback(key, value);
property === 'open' && value
? console.log('FooBar is open!!!')
: console.log('keep waiting');
});
console.log(FooBarObserver.open) // false
FooBarObserver.open = true // FooBar is open!!!