Proxy:
可以理解成代理对象。目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截
使用时需要实例化对象
通过代理对象控制真实对象的操作,如果没加限制就直接交给真实对象,有限制要先通过限制
下面是 Proxy 支持的拦截操作一览,一共 13 种。
get(target, propKey, receiver):拦截对象属性的读取,比如 proxy.foo 和 proxy['foo'] 。
set(target, propKey, value, receiver):拦截对象属性的设置,比如 proxy.foo = v 或 proxy['foo'] = v ,返回一个布尔值。
has(target, propKey):拦截 propKey in proxy 的操作,返回一个布尔值。
deleteProperty(target, propKey):拦截 delete proxy[propKey] 的操作,返回一个布尔值。
ownKeys(target):拦截 Object.getOwnPropertyNames(proxy) 、 Object.getOwnPropertySymbols(proxy) 、 Object.keys(proxy) 、 for...in 循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。
getOwnPropertyDescriptor(target, propKey):拦截 Object.getOwnPropertyDescriptor(proxy, propKey) ,返回属性的描述对象。
defineProperty(target, propKey, propDesc):拦截 Object.defineProperty(proxy, propKey, propDesc) 、 Object.defineProperties(proxy, propDescs) ,返回一个布尔值。
preventExtensions(target):拦截 Object.preventExtensions(proxy) ,返回一个布尔值。
getPrototypeOf(target):拦截 Object.getPrototypeOf(proxy) ,返回一个对象。
isExtensible(target):拦截 Object.isExtensible(proxy) ,返回一个布尔值。
setPrototypeOf(target, proto):拦截 Object.setPrototypeOf(proxy, proto) ,返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如 proxy(...args) 、 proxy.call(object, ...args) 、 proxy.apply(...) 。
construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(...args) 。
Reflect:
将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty ),放到 Reflect 对象上
修改某些 Object 方法的返回结果,让其变得更合理
(1)Reflect.defineProperty(target, property, attributes)
没有属性就新增属性,有属性就改值
(2)Reflect.has(Object, 'assign')
判断对象是否包含属性
(3)Reflect对象的方法与 Proxy对象的方法一一对应
...
Reflect对象一共有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)
//真实对象
var trueObj = {};
//代理对象的参数:
//第一个是真实对象的引用,第二个是限制规则
var obj = new Proxy(trueObj, {
//代理对象提供get读取器,读取真实对象的属性值
get: function (target, propKey, receiver) {
return Reflect.get(target, propKey, receiver);
},
//代理对象提供set赋值器,给真实对象的属性赋值
set: function (target, propKey, value, receiver) {
if(value < 0){
value = 18;
}
return Reflect.set(target, propKey, value, receiver);
}
});
obj.count = -10;
console.log(trueObj);
//规则
var handler = {
get: function(target, name) {
if (name === 'prototype') {
return Object.prototype;
}
return 'Hello, ' + name;
},
apply: function(target, thisBinding, args) {
return args[0];
},
construct: function(target, args) {
return {value: args[1]};
}
};
//创建代理对象 真实对象
var fproxy = new Proxy(function(x, y) {
return x + y;
}, handler);
console.log(fproxy(1, 2)); // 1 调用 apply
console.log(new fproxy(1, 2)); // {value: 2} 调用 construct
fproxy.prototype === Object.prototype // true 调用 get
fproxy.foo === "Hello, foo" // true