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() 方法类似。
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为其初始化参数的对象实例。
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 值指示了属性是否被成功定义。
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 值表明该属性是否被成功删除。
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值。
返回值 属性的值。
// 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。
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。
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 类型的对象指示是否存在此属性。
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 值表明该对象是否可扩展。
// 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。
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 值表明目标对象是否成功被设置为不可扩展。
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 值表明是否成功设置属性。
// 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 值表明是否原型已经成功设置。
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 方法是一一对应的。
- Reflect.apply()
- Reflect.construct()
- Reflect.defineProperty()
- Reflect.deleteProperty()
- Reflect.get()
- Reflect.getOwnPropertyDescriptor()
- Reflect.getPrototypeOf()
- Reflect.has()
- Reflect.isExtensible()
- Reflect.ownKeys()
- Reflect.preventExtensions()
- Reflect.set()
- Reflect.setPrototypeOf()