# Proxy
Proxy 用于修改某些操作默认行为,等同于在语言层面修,对编程语言进行编程,听说下版本的vue就会用Proxy,替代Object.defineProperty
可以理解成,在目标对象之前设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截
let proxy = new Proxy(target, handler);
//target参数表示所要拦截的目标对象
//handler参数也是一个对象,用来定制拦截行为
let person = {
name: "张三"
};
let proxy = new Proxy(person, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
proxy.name // "张三"
proxy.age // 抛出一个错误
拦截操作共13种,常用的如下:
- get(target, propKey, receiver):拦截对象属性的读取
- set(target, propKey, value, receiver):拦截对象属性的设置,返回布尔值
- has(target, propKey):拦截
propKey in proxy
的操作,返回一个布尔值 - deleteProperty(target, propKey):拦截
delete proxy[propKey]
的操作,返回一个布尔值。 - defineProperty(target, propKey, propDesc):拦截
Object.defineProperty(proxy, propKey, propDesc)
、Object.defineProperties(proxy, propDescs)
,返回一个布尔值。 - construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如
new proxy(...args)
。 - apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如
proxy(...args)
、proxy.call(object, ...args)
、proxy.apply(...)
注意点:在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理。有些原生对象的内部属性,只有通过正确的this才能拿到,所以 Proxy 也无法代理这些原生对象的属性。如new Date()
# Reflect
Reflect对象与Proxy对象一样,操作对象的新API
- 将Object对象上方法放到Reflect上
- 修改Object方法的返回结果,使其更合理,
- 并让Object操作变为函数行为
Reflect对象的方法与Proxy对象的方法一一对应,一共13个
- Reflect.apply(target, thisArg, args)
- Reflect.construct(target, args)
- Reflect.get(target, name, receiver)
- Reflect.set(target, name, value, receiver)
- Reflect.defineProperty(target, name, desc)
- Reflect.deleteProperty(target, name)
- Reflect.has(target, name)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, name)
- Reflect.getPrototypeOf(target)
- Reflect.setPrototypeOf(target, prototype)
let obj = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
},
}
Reflect.get(obj, 'foo') // 1
Reflect.set(obj, 'bar', 3)//3
// 旧写法
'foo' in obj // true
Reflect.has(obj, 'foo') // true
// 删除 旧写法
delete obj.foo;
// 新写法
Reflect.deleteProperty(obj, 'foo');
function MyDate() {
/*…*/
}
// 旧写法
Object.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
// 新写法
Reflect.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
//实现观察者模式Observer mode,函数自动观察数据对象
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set});
function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
queuedObservers.forEach(observer => observer());
return result;
}
← symbol Promise (重点) →