ES6 Reflect初探
Reflect
基本概念
与proxy对象一样,也是ES6为了操作对象而提供的新API
设计目的
- 将object对象的一些属于语言内部的方法(比如Object.defineProperty),放到reflect对象上.也就是说在reflect对象上将拿到语言内部的方法
- 修改某些object方法的返回结果,让其变得合理.比如, Object.defineProperty(obj, name, desc) 在无法定义属性时,会抛出一个错误,而 Reflect.defineProperty(obj, name, desc) 则会返回 false
- 让object操作都变成函数行为.某些object操作是命令式,比如
name in obj
和delete obj[name]
,而Reflect.has(obj,name)
和Reflect.deletePoroerty(obj,name)
让它们变为函数行为 - Reflect对象的方法和Proxy对象的方法一一对应,只要是proxy对象的方法,就能在reflect对象上找到相应的方法.这样proxy对象就可以方便的调用对应的reflect方法,完成默认行为.也就是说,无论proxy怎么修改默认行为,总可以在reflect上获取
静态方法
-
Reflect.get(target,name,receiver)查找并返回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 baz的get重新定义了 var myReceiverObject = { foo: 4, bar: 4, }; Reflect.get(myObject, 'baz', myReceiverObject) // 8 这里指的是this指向了receiver
-
Reflect.set(target,name,value,receiver):设置target对象的name属性等于value.如果第一个参数不是对象报错.用法和get一致.唯一注意的是:Reflect.set会触发Proxy.defineProperty拦截(Reflect.set在Proxy.set拦截中使用)
-
Reflect.has(obj,name):对应
name in obj
中的in运算符.如果第一个参数不是对象,reflect.has和in运算符都会报错 -
Reflect.deleteProperty(obj, name):等同于delete obj[name],用于删除对象的属性.返回一个布尔值,删除成功或要删除的属性不存在,返回true;删除失败,被删除的属性依然存在,返回false
-
Reflect.construct(target, args):等同于new target(…args),提供了一种不使用new来创建构造函数的方法
function Greeting(name) { this.name = name; } // new 的写法 const instance = new Greeting('张三'); // Reflect.construct 的写法 const instance = Reflect.construct(Greeting, ['张三']);
-
Reflect.getPrototypeOf(obj):用于读取对象的__proto__属性,对应Object.getPrototypeOf(obj).唯一的区别是如果参数不是对象,Object.getPrototypeOf(obj)会将其转为对象,而Reflect.getPrototypeOf(obj)会报错
-
Reflect.setPrototypeOf(obj, newProto):用于设置对象的__proto__属性,返回第一个参数对象,对应Object.setPrototypeOf(obj, newProto).
(1) 如果第一个参数不是对象,Object.setPrototypeOf(obj, newProto)会返回第一个参数本身,而Reflect.setPrototypeOf(obj, newProto)会报错
(2) 如果第一个参数是null或undefined,它们都会报错 -
Reflect.apply(func, thisArg, args):等同于Function.prototype.apply.call(func,thisArg,args),用于绑定this对象后执行给定函数
-
Reflect.defineProperty(target, propertyKey,attributes):基本等同于Object.defineProperty,用来为对象定义属性.推荐使用Reflect.defineProperty(target, propertyKey,attributes),因为另一个会被逐渐替代.如果Reflect.defineProperty第一个参数不是对象,就会抛出错误
-
Reflect.getOwnPropertyDescriptor(target,propertyKey),基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象.唯一的区别是:如果第一个参数不是对象,Object.getOwnPropertyDescriptor不报错,返回undefined.而Reflect.getOwnPropertyDescriptor会抛出错误,表示参数非法
-
Reflect.isExtensible (target):对应Object.isExtensible,返回一个布尔值,表示当前对象是否可以扩展.区别在于:如果参数不是对象,Object.isExtensible会返回false,因为非对象本来就是不可扩展的,而Reflect.isExtensible会报错
-
Reflect.preventExtensions(target):对应Object.preventExtensions方法,用于让一个对象的变得不可扩展,返回一个布尔值,表示是否操作成功.区别是:如果参数不是对象,Object.preventExtensions 在 ES5 环境报错,在 ES6 环境返回传入的参数.而Reflect.preventExtensions 会报错
-
Reflect.ownKeys (target):用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames 与 Object.getOwnPropertySymbols 之和.即可以获取普通的键名,也可以获取Symbol值的键名