一、Proxy
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作
var proxy = new Proxy(target, handler);
Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。
<script>
var target = {
name: '小蘑菇',
age: 20
};
var handler = {
set(target, key, value) {
if (key == 'age') {
if (value < 0) {
console.warn('年龄设置不合法');
} else {
console.log('设置了' + key, value);
target[key] = value;
}
} else {
console.log('设置了' + key, value);
target[key] = value;
}
},
get(target, key) {
console.log(key, '获取了', target[key]);
}
}
var proxy = new Proxy(target, handler);
</script>
二、Reflect
1、目的
Reflect对象的设计目的有这样几个。
(1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。
(2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
// 老写法
try {
Object.defineProperty(target, property, attributes);
// success
} catch (e) {
// failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
(3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
// 老写法
'assign' in Object // true
// 新写法
Reflect.has(Object, 'assign') // true
(4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
有了Reflect对象以后,很多操作会更易读。
// 老写法
Function.prototype.apply.call(Math.floor, undefined, [1.75]) // 1
// 新写法
Reflect.apply(Math.floor, undefined, [1.75]) // 1
这里简单介绍一下常用的方法
<script>
var obj = {
name: '小明',
age: 20,
leg: 2
};
var name = Reflect.get(obj, 'name');
console.log(name);
Reflect.set(obj, 'name', '李华');
console.log(obj);
// 检测是否含有
var flag = Reflect.has(obj, 'leg');
console.log(flag);
//获得键名
var keys = Reflect.ownKeys(obj);
console.log(keys);
</script>