The methods of the Reflect object translate this sentence into English.
Reflect
is a new built-in object introduced in ECMAScript 6 that provides methods to intercept JavaScript operations. These methods correspond one-to-one with the methods of the Proxy
object. They standardize object operations, with some methods replacing the older Object
-based approaches.
Reflect.apply()
Calls a function with a specified this
value and an array of arguments, equivalent to Function.prototype.apply()
but more intuitive:
function sum(a, b) {
return a + b;
}
// Traditional way
sum.apply(null, [1, 2]); // 3
// Reflect way
Reflect.apply(sum, null, [1, 2]); // 3
When dynamically invoking functions, Reflect.apply()
provides clearer semantics. It is particularly useful when working with Proxy
:
const proxy = new Proxy(sum, {
apply(target, thisArg, args) {
console.log(`Calling ${target.name} function`);
return Reflect.apply(target, thisArg, args);
}
});
proxy(1, 2); // Logs output and returns 3
Reflect.construct()
Similar to the new
operator for creating instances but supports initialization via an array of arguments:
class Person {
constructor(name) {
this.name = name;
}
}
// Traditional way
new Person('Zhang San');
// Reflect way
Reflect.construct(Person, ['Zhang San']);
This method is especially useful for dynamically creating instances, such as in pluggable class factories:
function createInstance(Constructor, ...args) {
return Reflect.construct(Constructor, args);
}
const person = createInstance(Person, 'Li Si');
Reflect.get()
Retrieves the value of an object property and supports a receiver
parameter to change this
binding:
const obj = { x: 1, y: 2 };
Reflect.get(obj, 'x'); // 1
// Using receiver to change `this`
const receiver = { x: 10 };
Reflect.get(obj, 'x', receiver); // Still returns 1, but `this` points to `receiver` during the operation
Works seamlessly with Proxy
's get
trap:
const proxy = new Proxy(obj, {
get(target, property, receiver) {
console.log(`Accessing property ${property}`);
return Reflect.get(target, property, receiver);
}
});
proxy.x; // Logs output and returns 1
Reflect.set()
Sets the value of an object property and returns a boolean indicating success:
const obj = {};
Reflect.set(obj, 'x', 1); // true
obj.x; // 1
// Fails for read-only properties
const frozen = Object.freeze({ x: 1 });
Reflect.set(frozen, 'x', 2); // false
The receiver
parameter can change this
in setters:
const obj = {
_x: 0,
set x(value) {
this._x = value;
}
};
const receiver = {};
Reflect.set(obj, 'x', 1, receiver);
receiver._x; // 1
obj._x; // 0
Reflect.has()
Checks if an object contains a property, replacing the in
operator:
const obj = { x: 1 };
'x' in obj; // true
Reflect.has(obj, 'x'); // true
// Checks prototype chain properties
Reflect.has(obj, 'toString'); // true
Can intercept in
operations in Proxy
:
const proxy = new Proxy(obj, {
has(target, property) {
console.log(`Checking property ${property}`);
return Reflect.has(target, property);
}
});
'x' in proxy; // Logs output and returns true
Reflect.deleteProperty()
Deletes an object property, replacing the delete
operator:
const obj = { x: 1, y: 2 };
delete obj.x; // true
Reflect.deleteProperty(obj, 'y'); // true
obj; // {}
// Fails for non-configurable properties
const frozen = Object.freeze({ x: 1 });
Reflect.deleteProperty(frozen, 'x'); // false
Reflect.getOwnPropertyDescriptor()
Retrieves an object property's descriptor, safer than Object.getOwnPropertyDescriptor()
:
const obj = { x: 1 };
Reflect.getOwnPropertyDescriptor(obj, 'x');
// { value: 1, writable: true, enumerable: true, configurable: true }
// Returns `undefined` for non-existent properties
Reflect.getOwnPropertyDescriptor(obj, 'y'); // undefined
Reflect.defineProperty()
Defines or modifies an object property, replacing Object.defineProperty()
:
const obj = {};
Reflect.defineProperty(obj, 'x', {
value: 1,
writable: true
}); // true
// Returns `false` on failure instead of throwing an error
Reflect.defineProperty(Object.freeze({}), 'x', { value: 1 }); // false
Reflect.ownKeys()
Retrieves all own property keys (including Symbol
and non-enumerable properties):
const obj = {
[Symbol('id')]: 123,
x: 1,
y: 2
};
Object.defineProperty(obj, 'hidden', {
value: 'secret',
enumerable: false
});
Reflect.ownKeys(obj); // ['x', 'y', 'hidden', Symbol(id)]
Reflect.getPrototypeOf()
Retrieves an object's prototype, replacing Object.getPrototypeOf()
:
const obj = {};
Reflect.getPrototypeOf(obj) === Object.prototype; // true
// Works with Proxy
const proxy = new Proxy(obj, {
getPrototypeOf(target) {
console.log('Getting prototype');
return Reflect.getPrototypeOf(target);
}
});
Object.getPrototypeOf(proxy); // Logs output and returns Object.prototype
Reflect.setPrototypeOf()
Sets an object's prototype, replacing Object.setPrototypeOf()
:
const obj = {};
const proto = { x: 1 };
Reflect.setPrototypeOf(obj, proto); // true
obj.x; // 1
// Fails for non-extensible objects
Reflect.setPrototypeOf(Object.freeze({}), proto); // false
Reflect.isExtensible()
Checks if an object is extensible, replacing Object.isExtensible()
:
const obj = {};
Reflect.isExtensible(obj); // true
Object.freeze(obj);
Reflect.isExtensible(obj); // false
Reflect.preventExtensions()
Makes an object non-extensible, replacing Object.preventExtensions()
:
const obj = {};
Reflect.preventExtensions(obj); // true
Reflect.isExtensible(obj); // false
// Returns `true` for already non-extensible objects
Reflect.preventExtensions(Object.freeze({})); // true
Using Reflect with Proxy
Reflect
methods were designed to correspond one-to-one with Proxy
handler methods, enabling transparent proxying:
const logger = {
get(target, property, receiver) {
console.log(`GET ${property}`);
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
console.log(`SET ${property}=${value}`);
return Reflect.set(target, property, value, receiver);
},
// Other trap methods...
};
const data = { x: 1 };
const proxy = new Proxy(data, logger);
proxy.x; // Logs "GET x" and returns 1
proxy.y = 2; // Logs "SET y=2"
Differences from Object Methods
Although Reflect
methods are similar to Object
methods, there are key differences:
- Return value handling differs:
Object.defineProperty(obj, 'x', { value: 1 }); // Returns obj
Reflect.defineProperty(obj, 'x', { value: 1 }); // Returns boolean
- Error handling differs:
// Object methods throw errors on failure
Object.defineProperty(Object.freeze({}), 'x', { value: 1 }); // Throws TypeError
// Reflect methods return false
Reflect.defineProperty(Object.freeze({}), 'x', { value: 1 }); // false
- More consistent parameter handling:
// Object.getPrototypeOf(1) throws an error
Reflect.getPrototypeOf(1); // Returns Number.prototype
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:Proxy的捕获器(trap)
下一篇:数据绑定与观察