Reflect对象
About
随着学习的深入,我逐渐对JavaScript
有了更宏观的认识,之前在工作中遇到的一些问题也得到了解释,我觉得学习就是这样,从微观到宏观,总有一天我吃透Javascript
的架构,请继续加油!
1. Reflect概述
Reflect
对象与Proxy
对象一样,也是 ES6 为了操作对象而提供的新 API
。针对Reflect
的设计目的来说,我觉得大概分为四点:
1.1 简化Object
对象
从 ES2015 开始,官方有意识的去调整Javascript
的架构,使得其结构更加清晰,比如将一些全局方法部署到专门的对象上,又如像Reflect
对象一样,将大部分以前属于Object
的静态方法移植到Reflect
对象上,以后可能Object
只承担构造函数的责任,即Object
上只有实例方法,将更多的操作对象的方法部署到专门的对象Reflect
上。
1.2 改变Object
静态方法的行为
之前,Object
的静态方法的行为不是很难统一,有的有返回值,有点没有返回值,有的返回一个对象实例,而有的又返回布尔值,很不规范,比如:
var a = {}
Object.setPrototypeOf(a, Array.prototype) // Array {}
Reflect.setPrototypeOf(a, Object.prototype) // true
Object.setPrototypeOf(1, Array.prototype) // 1
Reflect.setPrototypeOf(1, Object.prototype) // Uncaught TypeError
Reflect.setPrototypeOf(Object.freeze(a), Array.prototype) // false
通过上面的代码我们可以发现,Object.setPrototypeOf
总是返回第一个参数,我们并不知道操作是成功了还是失败了,是合法的还是非法的;但是Reflect.setPrototypeOf
就不一样了,它会返回一个布尔值来告诉你是成功还是失败,我们可以用if...else
去进行不同的操作。
1.3 让Objct
操作都变成函数式操作
Reflect
对象的方法都是函数式操作,即接受参数并有返回值,而Object
就不一样了:
var a = {
name: 'bing'
}
delete a.name // true
Reflect.deleteProperty(a, 'name') //true
变成函数式操作后,编程风格更严谨了
1.4 和Proxy
一一对应
Reflect
对象的方法与Proxy
对象的方法一一对应,只要是Proxy
对象的方法,就能在Reflect
对象上找到对应的方法。这就让Proxy
对象可以方便地调用对应的Reflect
方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy
怎么修改默认行为,你总可以在Reflect
上获取默认行为。
2. 静态方法
Reflect
大部分与Object
对象的同名方法的作用都是相同的,而且它与Proxy
对象的方法是一一对应的。这里只记录几个常见的,更多的方法请参阅原著。
2.1 get(target, name, recevier)
Reflect.get
方法查找并返回target
对象的name
属性,如果没有该属性,则返回undefined
。
var myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
},
}
Reflect.get(myObject, 'foo') // 1
Reflect.get(myObject, 'bar') // 2
Reflect.get(myObject, 'baz') // 3
get
方法接受的第三个参数receiver
是当target
对象中被读取的prop
有setter
方法的时候,setter
的this
可以绑定到reveiver
2.2 set(target, name, value, receiver)
Reflect.set()
方法会设置target
对象的name
属性的值为value
,如果name
的属性设置了setter
,那么setter
的this
就会绑定至rceivr
var myObject = {
foo: 4,
set bar(value) {
return this.foo = value;
},
};
var myReceiverObject = {
foo: 0,
};
Reflect.set(myObject, 'bar', 1, myReceiverObject);
myObject.foo // 4
myReceiverObject.foo // 1
2.3 has(obj, name)
该方法相当于in
运算符
var myObject = {
foo: 1,
};
// 旧写法
'foo' in myObject // true
// 新写法
Reflect.has(myObject, 'foo') // true
2.4 defineProprty(targeet, name, attriDescObj)
Reflect.defineProperty
方法基本等同于Object.defineProperty
,用来为对象定义属性。未来,后者会被逐渐废除,请从现在开始就使用Reflect.defineProperty
代替它。
function MyDate() {
/*…*/
}
// 旧写法
Object.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
// 新写法
Reflect.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
参考链接
作者:阮一峰