Skip to content

Reflect

Reflect 是一个内置的对象,它提供了拦截 JavaScript 操作的方法。这些方法与 proxy handler 对象的方法相对应。

1. Reflect.apply()

Reflect.apply(target, thisArgument, argumentsList)

target 目标函数。

thisArgument target 函数调用时绑定的 this 对象。

argumentsList target 函数调用时传入的实参列表,该参数应该是一个类数组的对象。

返回值 返回值是调用完带着指定参数和 this 值的给定的函数后返回的结果。

调用函数,与 Function.prototype.apply() 和 Function.prototype.call() 方法类似。

ts
console.log(Reflect.apply(Math.floor, undefined, [1.75]))
// Expected output: 1

console.log(Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]))
// Expected output: "hello"

console.log(Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index)
// Expected output: 4

console.log(Reflect.apply(''.charAt, 'ponies', [3]))
// Expected output: "i"

2. Reflect.construct()

对构造函数进行 new 操作,相当于执行 new target(...args)。

Reflect.construct(target, argumentsList[, newTarget])

target 被运行的目标构造函数

argumentsList 类数组,目标构造函数调用时的参数。

newTarget 可选 作为新创建对象的原型对象的 constructor 属性,参考 new.target 操作符,默认值为 target。

返回值 以target(如果newTarget存在,则为newTarget)函数为构造函数,argumentList为其初始化参数的对象实例。

ts
const d = Reflect.construct(Date, [1776, 6, 4])
console.log(d instanceof Date) // true
console.log(d.getFullYear()) // 1776

3. Reflect.defineProperty()

和 Object.defineProperty() 类似。如果设置成功就会返回 true

Reflect.defineProperty(target, propertyKey, attributes)

target 目标对象。

propertyKey 要定义或修改的属性的名称。

attributes 要定义或修改的属性的描述。

返回值 Boolean 值指示了属性是否被成功定义。

ts
let obj = {}
console.log(Reflect.defineProperty(obj, 'x', { value: 7 })) // true
console.log(obj.x) // 7

4. Reflect.deleteProperty()

作为函数的delete操作符,相当于执行 delete target[name]

Reflect.deleteProperty(target, propertyKey)

target 删除属性的目标对象。

propertyKey 需要删除的属性的名称。

返回值 Boolean 值表明该属性是否被成功删除。

ts
const obj = { x: 1, y: 2 }
Reflect.deleteProperty(obj, 'x') // true
obj // { y: 2 }

const arr = [1, 2, 3, 4, 5]
Reflect.deleteProperty(arr, '3') // true
arr // [1, 2, 3, , 5]

// 如果属性不存在,返回 true
Reflect.deleteProperty({}, 'foo') // true

// 如果属性不可配置,返回 false
Reflect.deleteProperty(Object.freeze({ foo: 1 }), 'foo') // false

5. Reflect.get()

获取对象身上某个属性的值,类似于 target[name]

Reflect.get(target, propertyKey[, receiver])

target 需要取值的目标对象

propertyKey 需要获取的值的键值

receiver 如果target对象中指定了getter,receiver则为getter调用时的this值。

返回值 属性的值。

ts
// Object
const obj = { x: 1, y: 2 }
Reflect.get(obj, 'x') // 1

// Array
Reflect.get(['zero', 'one'], 1) // "one"

// Proxy with a get handler
const x = { p: 1 }
const obj = new Proxy(x, {
	get(t, k, r) {
		return k + 'bar'
	},
})
Reflect.get(obj, 'foo') // "foobar"

6. Reflect.getOwnPropertyDescriptor()

类似于 Object.getOwnPropertyDescriptor()。如果对象中存在该属性,则返回对应的属性描述符,否则返回 undefined。

Reflect.getOwnPropertyDescriptor(target, propertyKey)

target 需要寻找属性的目标对象。

propertyKey 获取自己的属性描述符的属性的名称。

返回值 如果属性存在于给定的目标对象中,则返回属性描述符;否则,返回 undefined。

ts
Reflect.getOwnPropertyDescriptor({ x: 'hello' }, 'x')
// {value: "hello", writable: true, enumerable: true, configurable: true}

Reflect.getOwnPropertyDescriptor({ x: 'hello' }, 'y')
// undefined

Reflect.getOwnPropertyDescriptor([], 'length')
// {value: 0, writable: true, enumerable: false, configurable: false}

7. Reflect.getPrototypeOf()

类似于 Object.getPrototypeOf()。返回指定对象的原型。

Reflect.getPrototypeOf(target)

target 获取原型的目标对象。

返回值 给定对象的原型。如果给定对象没有继承的属性,则返回 null。

ts
const object1 = {
	property1: 42,
}

const proto1 = Reflect.getPrototypeOf(object1)

console.log(proto1)
// Expected output: Object {  }

console.log(Reflect.getPrototypeOf(proto1))
// Expected output: null

8. Reflect.has()

判断一个对象是否存在某个属性,和 in 运算符 的功能完全相同。

Reflect.has(target, propertyKey)

target 目标对象。

propertyKey 属性名,需要检查目标对象是否存在此属性。

返回值 一个 Boolean 类型的对象指示是否存在此属性。

ts
console.log(Reflect.has({ x: 0 }, 'x')) // true
console.log(Reflect.has({ x: 0 }, 'y')) // false

// 如果该属性存在于原型链中,返回 true
console.log(Reflect.has({ x: 0 }, 'toString'))

// Proxy 对象的 .has() 句柄方法
const obj = new Proxy(
	{},
	{
		has(t, k) {
			return k.startsWith('door')
		},
	}
)
console.log(Reflect.has(obj, 'doorbell')) // true
console.log(Reflect.has(obj, 'dormitory')) // false

9. Reflect.isExtensible()

类似于 Object.isExtensible(). 判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。

Reflect.isExtensible(target)

target 检查是否可扩展的目标对象。

返回值 返回一个 Boolean 值表明该对象是否可扩展。

ts
// New objects are extensible.
const empty = {}
Reflect.isExtensible(empty) // === true

// ...but that can be changed.
Reflect.preventExtensions(empty)
Reflect.isExtensible(empty) // === false

// Sealed objects are by definition non-extensible.
const sealed = Object.seal({})
Reflect.isExtensible(sealed) // === false

// Frozen objects are also by definition non-extensible.
const frozen = Object.freeze({})
Reflect.isExtensible(frozen) // === false

10. Reflect.ownKeys()

返回一个包含所有自身属性(不包含继承属性)的数组。(类似于 Object.keys(), 但不会受enumerable 影响).

Reflect.ownKeys(target)

target 获取自身属性键的目标对象。

返回值 由目标对象的自身属性键组成的 Array。

ts
const object1 = {
	property1: 42,
	property2: 13,
}

const array1 = []

console.log(Reflect.ownKeys(object1))
// Expected output: Array ["property1", "property2"]

console.log(Reflect.ownKeys(array1))
// Expected output: Array ["length"]

11. Reflect.preventExtensions()

类似于 Object.preventExtensions()。返回一个Boolean。 如果成功,对象将不再可扩展。

Reflect.preventExtensions(target)

target 阻止扩展的目标对象。

返回值 返回一个 Boolean 值表明目标对象是否成功被设置为不可扩展。

ts
const object1 = {}

console.log(Reflect.isExtensible(object1))
// Expected output: true

Reflect.preventExtensions(object1)

console.log(Reflect.isExtensible(object1))
// Expected output: false

12. Reflect.set()

将值分配给属性的函数。返回一个Boolean,如果更新成功,则返回true。

Reflect.set(target, propertyKey, value[, receiver])

target 设置属性的目标对象。

propertyKey 设置的属性的名称。

value 设置的值。

receiver 如果遇到 setter,receiver则为setter调用时的this值。

返回值 返回一个 Boolean 值表明是否成功设置属性。

ts
// Object
const obj = {}
Reflect.set(obj, 'prop', 'value') // true
obj.prop // "value"

// Array
const arr = ['duck', 'duck', 'duck']
Reflect.set(arr, 2, 'goose') // true
arr[2] // "goose"

// It can truncate an array.
Reflect.set(arr, 'length', 1) // true
arr // ["duck"];

// With just one argument, propertyKey and value are "undefined".
const obj = {}
Reflect.set(obj) // true
Reflect.getOwnPropertyDescriptor(obj, 'undefined')
// { value: undefined, writable: true, enumerable: true, configurable: true }

13. Reflect.setPrototypeOf()

设置对象原型的函数。返回一个 Boolean,如果更新成功,则返回 true。

Reflect.setPrototypeOf(target, prototype)

target 设置原型的目标对象。

prototype 对象的新原型(一个对象或 null)。

返回值 返回一个 Boolean 值表明是否原型已经成功设置。

ts
Reflect.setPrototypeOf({}, Object.prototype) // true

// It can change an object's [[Prototype]] to null.
Reflect.setPrototypeOf({}, null) // true

// Returns false if target is not extensible.
Reflect.setPrototypeOf(Object.freeze({}), null) // false

// Returns false if it cause a prototype chain cycle.
const target = {}
const proto = Object.create(target)
Reflect.setPrototypeOf(target, proto) // false

总结

Reflect 对象的方法和 Proxy 对象的 handler 方法是一一对应的。

  1. Reflect.apply()
  2. Reflect.construct()
  3. Reflect.defineProperty()
  4. Reflect.deleteProperty()
  5. Reflect.get()
  6. Reflect.getOwnPropertyDescriptor()
  7. Reflect.getPrototypeOf()
  8. Reflect.has()
  9. Reflect.isExtensible()
  10. Reflect.ownKeys()
  11. Reflect.preventExtensions()
  12. Reflect.set()
  13. Reflect.setPrototypeOf()

参考

MDN Reflect