Reflect 反射
Reflect 是 ECMAScript6 标准中的一个对象,名为“反射”。它用来代替原来 Object 对象身上的一些方法,比如用 Reflect.defineProperty
代替 Object.defineProperty
等等。
之所以要推出 Reflect
对象,是为了对原来一些混乱的 API 做一个更好的分类。
比如上面提到的 Object.defineProperty
方法,它可以对一个对象的属性做更底层的控制,比如 Vue2 中,就是用此方法对属性进行重写,从而能在读取属性值的时候做依赖收集,在更新属性值的值触发更新操作。再比如 Object.keys
方法,它可以读取一个对象身上的可枚举属性。像是这两个方法,其实本身和它们所依附的 Object
并没有多大关系。Object
更多的时候,是作为一个构造函数/类去使用,而不是形如 obj.xxx
这样作为一个对象去使用。
Reflect
的出现弥补了这一点。 Reflect
长得像是 String
,Number
,RegExp
一样,但其实更像是 Math
,只是一个普通的全局对象,而非一个构造函数,因此不能通过 new 运算符将其实例化,也不能作为一个函数来调用。下面都是错误的用法:
new Reflect();
Reflect()
上面提到的两个方法 Object.defineProperty
和 Object.keys
,都在 Reflect
身上有对应的实现,分别是 Reflect.defineProperty
和 Reflect.keys
。除了调用者变了,剩下的用法还和原来一样。除此之外,根据它的函数签名可知,它的返回值是一个 boolean
类型,这样我们还能知道它的操作是否成功:
ES 标准中的 Reflect
对象提供了 13 个静态方法,它们与 Proxy
对象能代理的 13 种操作是一一对应的,分别如下:
Reflect.apply()
:通过指定的参数列表发起对目标 (target) 函数的调用Reflect.construct()
:等同于 new 操作符,即实例化目标对象Reflect.defineProperty()
:基本等同于Object.defineProperty()
方法,唯一不同是返回布尔值。- 布尔值。返回值。eteProperty()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty):删除对象的属性,等同于 delete 操作符
Reflect.get()
:读取对象的属性Reflect.getOwnPropertyDescriptor()
:获取属性的属性描述符,当属性不存在时返回 undefinedReflect.getPrototypeOf()
:获取对象的原型对象Reflect.has()
:判断属性是否存在于对象或者原型链上,等同于 in 操作符Reflect.isExtensible()
:判断一个对象是否可扩展(即是否能够添加新的属性)Reflect.ownKeys()
:返回对象自身的属性集合,包含 Symbol 符号属性Reflect.preventExtensions()
:阻止新属性添加到对象Reflect.set()
:设置对象的属性值Reflect.setPrototypeOf()
:为对象设置新的原型对象
每个方法的具体作用就不再过多表述了,相信您诸位从这些命名,再结合以前使用过的 Object
上的方法,基本上可以做到见名知义了。