携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
介绍
Reflect是一个内建的对象,用来提供方法去拦截JavaScript的操作。Reflect不是一个函数对象,所以它是不可构造的,也就是说它不是一个构造器,你不能通过new操作符去新建或者将其作为一个函数去调用Reflect对象。Reflect的所有属性和方法都是静态的。
目的
说是为了将对象的属于语言内部的的方法,都放到Reflect对象上,就像Bom和Dom,未来新方法只部署到Reflect上,这个语法除了vue3里面看到使用了,Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。vue只是想拦截,并不是修改默认行为。
Relect的静态方法和proxy的静态方法一一对应,proxy可以重写任何一个方法,但是不能改变Relect上的静态方法,所以说Relect上的方法是安全的,不会被覆盖。而且尽可能的不抛出异常,把错误的处理尽可能返回false.
静态方法
get
Reflect.get(target,key,receiver),方法安全的返回target对象上的key属性,如果没有这个属性,那就是返回unfefined,和对象点属性名是一码事,所以有点脱裤子放屁的嫌疑,虽然是标准,但是大家使用率并不高,
var obj = {
name: "tom",
age: 19,
sex: 12,
}
var x1 = Reflect.get(obj, 'name');
var x2 = obj.name;
console.log(x1, x2); // 结果一摸一样
第三个参数receiver有点意思,当对象里面部署了读取函数(getter),我们要读的属性也正好是这个读取器,那么这个读取器里的this指向,就是这个receiver对象。这样和点出来的对象就不一样了。
var obj = {
name: "tom",
age: 19,
get desc() {
return "这个哥们名字是" + this.name + ',年龄为:' + this.age
}
}
var x1 = Reflect.get(obj, 'desc', {
name: "张三",
age: 88
});
var x2 = obj.desc
console.log(x1, x2);
// 这个哥们名字是张三,年龄为:88 这个哥们名字是tom,年龄为:19
剩下的方法都差不多,
- 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)
总结
这个方法确实感觉有些不优雅,毕竟每个公司都有一些不懂的人掌握着话语权,不过配置proxy拦截,使用确实是完美,能够安全执行最终想要的默认结果。但是如果对象正常读写都按这个来,可能就真的影响了使用效果,毕竟人们都希望少写代码。简而精吧