ECMAScript 6 笔记(16)- Reflect

原创 乘风逐月 随笔 ES6 58阅读 27 天前 举报

一、概述

Reflect 对象的设计目的:
(1)将 Object 对象的一些明显属于语言内部的方法(如Object.defineProperty),放到 Reflect 对象。现阶段,某些方法同时在 Object 和 Reflect 对象上部署,未来的新方法将只部署在 Reflect 对象上,即可用从 Reflect 对象上拿到语言的内部方法。

(2)修改某些 Object 方法的返回结果,让其变得更合理。如 Object.defineProperty(obj,name,desc) 在无法定义属性时,会抛出一个错误,而 Reflect.defineProperty(obj,name,desc) 则会返回 false。

(3)让 Object 操作都变成函数行为。某些 Object 操作是命令式,如 name in obj 和 delete obj[name],而 Reflect.has(obj,name) 和 Reflect.deleteProperty(obj,name) 让它们变成了函数行为。

(4)Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。这就让 Proxy 对象可以方便的调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。即不管 Proxy 怎么修改默认行为,总可以在 Reflect 上获取默认行为。

二、静态方法

Reflect 的静态方法与 Proxy 对象的方法一一对应。

1.Reflect.get(target,name,receiver)

Reflect.get 方法查找并返回 target 对象的 name 属性,如果没有该属性,则返回 undefined。
如果 name 属性部署了读取函数,则读取函数的 this 绑定 receiver。

如果第一个参数不是对象,Reflect.get 方法会报错。

2.Reflect.set(target,name,value,receiver)

Reflect.set 方法设置 target 对象的 name 属性值为 value。
如果 name 属性设置了赋值函数,则赋值函数的 this 绑定 receiver。

如果第一个参数

注意
如果 Proxy 对象和 Reflect 对象联合使用,前者拦截赋值操作,后者完成赋值的默认行为,而且如果传入了 receiver,那么 Reflect.set 会触发 Proxy.defineProperty 拦截。

上例中,Proxy.set 拦截里面使用了 Reflect.set,而且传入了 receiver,导致触发 Proxy.defineProperty 拦截。这是因为 Proxy.set 的 receiver 参数总是指向当前的 Proxy 实例即 obj,而 Reflect.set 一旦传入了 receiver,就会将属性赋值到 receiver 上面即 obj,导致触发 defineProperty 拦截。
如果 Reflect.set 没有传入 receiver,那么就不会触发 defineProperty 拦截。

3.Reflect.has(obj,name)

Reflect.has 方法对应 name in obj 里面的 in 运算符。
如果第一个参数不是对象,Reflect.has 和 in 运算符都会报错。

4.Reflect.deleteProperty(obj,name)

Reflect.deleteProperty 方法等同于 delete obj[name],用于删除对象的属性。
该方法返回一个布尔值。如果删除成功,或者被删除的属性不存在,返回 true;删除失败,被删除的属性依然存在,返回 false。

5.Reflect.construct(target,args)

Reflect.construct 方法等同于 new target(...args),这提供了一种不使用 new,来调用构造函数的方法。

6.Reflect.getPropertyOf(obj)

Reflect.getPropertyOf 方法用于读取对象的 双下划綫prop 属性,对于 Object.getPrototypeOf(obj)。

Reflect.getPrototypeOf 和 Object.getPropertyOf 的一个区别是:
如果参数不是对象,Object.getPrototypeOf 会将参数转为对象,然后再运行,而 Reflect.getPrototypeOf 会报错。

7.Reflect.setPrototypeOf(obj,newProto)

Reflect.setPrototype 方法用于设置目标对象的原型,对应 Object.setPrototypeOf(obj,newProto) 方法。该方法返回一个布尔值,表示是否设置成功,成功返回 true,失败返回 false。

注:
a. 如果第一个参数不是对象,Reflect.setPrototypeOf 会报错,而 Object.setPrototypeOf 会返回第一个参数本身。
b. 如果第一个参数是 null 或 undefined,Reflect.setPrototypeOf 和 Object.setPrototypeOf 都会报错。

8.Reflect.apply(func,thisArg,args)

Reflect.apply 方法等同于 Function.prototype.apply.call(func,thisArg,args),用于绑定 this 对象后执行给定函数。

9.Reflect.defineProperty(target,propertyKey,attributes)

Reflect.defineProperty 方法等同于 Object.defineProperty,用来为对象定义属性。

如果 Reflect.defineProperty 的第一个参数不是对象,就会抛出错误。
这个方法可以与 Proxy.defineProperty 配合使用。

10.Reflect.getOwnPropertyDescriptor(target,propertyKey)

Reflect.getOwnPropertyDescriptor 基本等同于 Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象,将来会替换掉后者。

11.Reflect.isExtensible(target)

Reflect.isExtensible 方法对应 Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展。
如果参数不是对象,Object.isExtensible 会返回 false,因为非对象本来就是不可扩展的,而 Reflect.isExtensible 会报错。

12.Reflect.preventExtensions(target)

Reflect.preventExtensions 对应 Object.preventExtensions 方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功。
如果参数不是对象,Reflect.preventExtensions 会报错。

13.Reflect.ownKeys(target)

Reflect.ownKeys(target) 方法用于返回对象的所有属性,基本等同于 Object.getOwnPropertyNames 与 Object.getOwnPropertySymbols 之和。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复