写在前面
Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与proxy handlers (en-US)
的方法相同。Reflect
不是一个函数对象,因此它是不可构造的。
Reflect是什么?
与大多数全局对象不同
Reflect
并非一个构造函数,所以不能通过new运算符
对其进行调用,或者将Reflect
对象作为一个函数来调用。Reflect
的所有属性和方法都是静态的(就像Math
对象)。
Reflect
对象提供了以下静态方法,这些方法与proxy handler methods (en-US)
的命名相同.其中的一些方法与
Object
相同, 尽管二者之间存在 【某些细微上的差别】
Reflect
对象的设计目的有这样几个:
(1) 将Object
对象的一些明显属于语言内部的方法(比如Object.defineProperty
),放到Reflect
对象上。现阶段,某些方法同时在Object
和Reflect
对象上部署,未来的新方法将只部署在Reflect
对象上。也就是说,从Reflect
对象上可以拿到语言内部的方法。
(2) 修改某些Object
方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)
在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)
则会返回false
。
// 老写法
try {
Object.defineProperty(target, property, attributes);
// success
} catch (e) {
// failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
(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的静态方法
Reflect
对象一共有 13 个静态方法:
-
Reflect.apply(target, thisArgument, argumentsList)
:对一个函数进行调用操作,同时可以传入一个数组作为调用参数。和Function.prototype.apply()
功能类似 -
Reflect.construct(target, argumentsList[, newTarget])
:对构造函数进行new
操作,相当于执行new target(...args)
-
Reflect.defineProperty(target, propertyKey, attributes)
:和Object.defineProperty()
类似。如果设置成功就会返回true
-
Reflect.deleteProperty(target, propertyKey)
:作为函数的delete
操作符,相当于执行delete target[name]
-
Reflect.get(target, propertyKey[, receiver])
:获取对象身上某个属性的值,类似于target[name]
-
Reflect.getOwnPropertyDescriptor(target, propertyKey)
:类似于Object.getOwnPropertyDescriptor()
。如果对象中存在该属性,则返回对应的属性描述符, 否则返回undefined
. -
Reflect.getPrototypeOf(target)
:类似于Object.getPrototypeOf()
-
Reflect.has(target, propertyKey)
:判断一个对象是否存在某个属性,和in
运算符的功能完全相同。 -
Reflect.isExtensible(target)
:类似于Object.isExtensible()
-
Reflect.ownKeys(target)
:返回一个包含所有自身属性(不包含继承属性)的数组。(类似于Object.keys()
, 但不会受enumerable影响
). -
Reflect.preventExtensions(target)
:类似于Object.preventExtensions()
。返回一个Boolean
-
Reflect.set(target, propertyKey, value[, receiver])
:将值分配给属性的函数。返回一个Boolean
,如果更新成功,则返回true
。 -
Reflect.setPrototypeOf(target, prototype)
:设置对象原型的函数. 返回一个Boolean
, 如果更新成功,则返回true。
上面这些方法的作用,大部分与
Object
对象的同名方法的作用都是相同的,而且它与Proxy
对象的方法是一一对应的。