ES6之Reflect

1、什么是Reflect?为操作对象而提供的新API
2、为什么要设计Reflect?(1)将Object对象的属于语言内部的方法放到Reflect对象上,即从Reflect对象上拿Object对象内部方法。(2)将用 老Object方法 报错的情况,改为返回false老写法
try {Object.defineProperty(target, property, attributes);// success} catch (e) {// failure}新写法
if (Reflect.defineProperty(target, property, attributes)) {// success} else {// failure}
(3)让Object操作变成函数行为老写法(命令式写法)’name’ in Object //true新写法Reflect.has(Object,’name’) //true(4)Reflect与Proxy是相辅相成的,在Proxy上有的方法,在Reflect就一定有
let target={}let handler={set(target,proName,proValue,receiver){//确认对象的属性赋值成功let isSuccess=Reflect.set(target,proName,proValue,receiver)if(isSuccess){console.log(“成功”)}return isSuccess}}let proxy=new Proxy(target,handler)确保对象的属性能正确赋值,广义上讲,即确保对象的原生行为能够正常进行,这就是Reflect的作用
3、Reflect的API注:由于和Proxy的API一致,所以参数就不解释了。
(1)Reflect.get(target,property,receiver)查找并返回target对象的property属性例1:
let obj={name:”chen”,}let result=Reflect.get(obj,”name”)console.log(result) //chen例2:
let obj={//属性yu部署了getter读取函数get yu(){//this返回的是Reflect.get的receiver参数对象return this.name+this.age}}
let receiver={name:”shen”,age:”18″,}let result=Reflect.get(obj,”yu”,receiver)console.log(result) //shen18注意:如果Reflect.get()的第一个参数不是对象,则会报错。
(2)Reflect.set(target,propName,propValue,receiver)设置target对象的propName属性为propValue例1:
let obj={name:”chen”}
let result=Reflect.set(obj,”name”,”shi”)console.log(result) //trueconsole.log(obj.name) //shi例2:原理同3(1)的例2
let obj={age:38,set setAge(value){return this.age=value}}
let receiver={age:28}
let result=Reflect.set(obj,”setAge”,18,receiver)console.log(result) //trueconsole.log(obj.age) //38console.log(receiver.age) //18(3)Reflect.set与Proxy.set联合使用,并且传入receiver,则会进行定义属性操作
let obj={name:”chen”}
let handler={set(target,key,value,receiver){console.log(“Proxy拦截赋值操作”)//Reflect完成赋值操作Reflect.set(target,key,value,receiver)},defineProperty(target,key,attribute){console.log(“Proxy拦截定义属性操作”)//Reflect完成定义属性操作Reflect.defineProperty(target,key,attribute)}}
let proxy=new Proxy(obj,handler)proxy.name=”ya”//Proxy拦截赋值操作//Proxy拦截定义属性操作
*
为什么Reflect.set()传入receiver参数,就会触发定义属性的操作?因为Proxy.set()中的receiver是Proxy的实例(详情见这篇文章),即obj,而Reflect.set一旦传入receiver,就会将属性赋值到receiver上面,也是obj,所以就会触发defineProperty拦截。
(4)Reflect.has(obj,name)
var obj= {name: “chen”,};老写法’name’ in obj // true新写法Reflect.has(obj, ‘name’) // true
(5)Reflect.deleteProperty(obj, name)删除对象的属性老写法:delete obj.name;新写法Reflect.deleteProperty(obj, ‘name’);(6)Reflect.construct(target, args)
function Person(name) {this.name = name;}new 的写法let person= new Person(‘chen’)Reflect.construct 的写法let person = Reflect.construct(Person, [‘chen’]);
(7)Reflect.getPrototypeOf(obj)用于读取对象的proto属性,对应Object.getPrototypeOf(obj)
(8)Reflect.setPrototypeOf(obj, newProto)设置目标对象的原型(prototype),对应Object.setPrototypeOf(obj, newProto)方法
(9)Reflect.apply(func, thisArg, args)继承目标对象的特定方法let array=[1,2,3,4,5,6]老写法:
let small= Math.min.apply(Math, array) //1let big = Math.max.apply(Math, array) //6let type = Object.prototype.toString.call(small) //”[object Number]”新写法:
const small= Reflect.apply(Math.min, Math, array)const big = Reflect.apply(Math.max, Math, array)//第三个参数是Object类型的就好,因为调用的是Object的原型方法toStringconst type = Reflect.apply(Object.prototype.toString, small, [])(10)Reflect.defineProperty(target, propertyKey, attributes)
function MyDate() {……}老写法
Object.defineProperty(MyDate, ‘now’, {value: () => Date.now()});新写法
Reflect.defineProperty(MyDate, ‘now’, {value: () => Date.now()});与Proxy.defineProperty配合使用
let proxy = new Proxy({}, {defineProperty(target, prop, descriptor) {console.log(descriptor);return Reflect.defineProperty(target, prop, descriptor);}});
proxy .name= ‘chen’;// {value: “chen”, writable: true, enumerable: true, configurable: true}p.name // “chen”如上,Proxy.defineProperty对属性赋值设置拦截,然后使用Reflect.defineProperty完成赋值
(11)Reflect.getOwnPropertyDescriptor(target, propertyKey)基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象
(12)Reflect.isExtensible (target)对应Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展
(13)Reflect.preventExtensions(target)对应Object.preventExtensions方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功
(14)Reflect.ownKeys (target)用于返回对象的所有属性
4、使用Proxy和Reflect实现观察者模式请参考Javascript观察者模式

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理