Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。
Reflect不是一个函数对象,它不是一个构造函数,不可以使用 new 运算符对其调用。Reflect的所有属性和方法都是静态的(就像Math对象)。
let obj = {
name: 'xingxing',
age: 12,
list: ['a', 'b', 'c'],
json: { d: 1, f: 2 },
[Symbol('ee')]: 'symbol_demo'
}
1. Reflect.getPrototypeOf(target) [返回指定对象的原型]
静态方法 Reflect.getPrototypeOf() 与 Object.getPrototypeOf()方法几乎是一样的。都是返回指定对象的原型(即内部的 [[Prototype]] 属性的值)。
console.log(Reflect.getPrototypeOf(obj)); // [Object: null prototype] {} nodejs执行结果
console.log(Object.getPrototypeOf(obj)); // [Object: null prototype] {} nodejs执行结果
2.1 Reflect.setPrototypeOf(target, prototype) [设置对象原型的函数,返回一个 Boolean]
除了返回类型以外,静态方法 Reflect.setPrototypeOf() 与 Object.setPrototypeOf()方法是一样的。它可设置对象的原型(即内部的 [[Prototype]] 属性)为另一个对象或 null如果操作成功返回 true,否则返回 false。
const parent = { foo: 'bar' };
console.log(Reflect.setPrototypeOf(obj, parent)); // true
console.log(Reflect.getPrototypeOf(obj)); // {foo: 'bar'}
console.log(Reflect.setPrototypeOf(obj, null)); // true
console.log(Reflect.getPrototypeOf(obj)); //null
const obj2 = {};
console.log(Reflect.setPrototypeOf(Object.freeze(obj2), null)); // false
console.log(Reflect.getPrototypeOf(obj2)); //[Object: null prototype] {} nodejs执行结果
const obj3 = 3
const parent3 = { foo3: 'bar3' };
console.log(Reflect.setPrototypeOf(obj3, parent2)); // Uncaught TypeError: Reflect.setPrototypeOf called on non-object
console.log(Reflect.getPrototypeOf(obj3)); // Uncaught TypeError: Reflect.getPrototypeOf called on non-object
2.2 Object.setPrototypeOf(target, prototype) [设置对象原型的函数,返回指定的对象]
Object.setPrototypeOf() 静态方法可以将一个指定对象的原型(即内部的 [[Prototype]] 属性)设置为另一个对象或者 null。
const parent2 = { foo2: 'bar2' };
console.log(Object.setPrototypeOf(obj, parent2)); // 返回指定的对象(obj)
console.log(Object.getPrototypeOf(obj)); // {foo2: 'bar2'}
const obj4 = 4
const parent4 = { foo4: 'bar4' };
console.log(Object.setPrototypeOf(obj4, parent4)); // 4
console.log(Object.getPrototypeOf(obj4)); // Number {}
3.1 Reflect.isExtensible(target) [判断一个对象是否可扩展(即是否能够添加新的属性),返回一个Boolean]
静态方法 Reflect .isExtensible() 判断一个对象是否可扩展(即是否能够添加新的属性)。与它 Object.isExtensible()方法相似,但有一些不同。
console.log(Reflect.isExtensible(obj)); // true
console.log(Reflect.isExtensible(1)); // Uncaught TypeError: Reflect.isExtensible called on non-object
3.2 Object.isExtensible() [判断一个对象是否可扩展(即是否能够添加新的属性),返回一个Boolean]
与 Object.isExtensible() 的不同点
如果该方法的第一个参数不是一个对象(原始值),那么将造成一个 TypeError 异常。对于 Object.isExtensible(),非对象的第一个参数会被强制转换为一个对象。
console.log(Object.isExtensible(obj)); // true
console.log(Object.isExtensible(1)); // false
4.1Reflect.preventExtensions() [阻止新属性添加到对象,返回一个Boolean]]
静态方法 Reflect.preventExtensions() 方法阻止新属性添加到对象 (例如:防止将来对对象的扩展被添加到对象中)。该方法与 Object.preventExtensions()相似,但有一些不同点。
console.log(Reflect.preventExtensions(obj)); // true
console.log(Reflect.isExtensible(obj)); // false
console.log(Reflect.preventExtensions(1)); // Uncaught TypeError: Reflect.preventExtensions called on non-object
4.2 Object.preventExtensions() [阻止新属性添加到对象,返回已经不可扩展的对象。]
Object.preventExtensions() 静态方法可以防止新属性被添加到对象中(即防止该对象被扩展)。它还可以防止对象的原型被重新指定。
console.log(Object.preventExtensions(obj)); // obj对象
console.log(Object.preventExtensions(1)); // 1
5.1 Reflect.getOwnPropertyDescriptor(target, propertyKey) [如果对象中存在该属性,则返回对应的属性描述符,否则返回 undefined]
静态方法 Reflect.getOwnPropertyDescriptor() 与 Object.getOwnPropertyDescriptor()方法相似。如果对象中存在该属性,则返回对应的属性描述符,否则返回 undefined。与 [Object.getOwnPropertyDescriptor()] 的唯一不同在于如何处理非对象目标。
console.log(Reflect.getOwnPropertyDescriptor(obj, "name"));// {value: 'xingxing', writable: true, enumerable: true, configurable: true}
console.log(Reflect.getOwnPropertyDescriptor(obj, "age1")); // undefined
console.log(Reflect.getOwnPropertyDescriptor([], 'length'));// { value: 0, writable: true, enumerable: false, configurable: false }
console.log(Reflect.getOwnPropertyDescriptor([1, 2, 4], 'length'));// { value: 3, writable: true, enumerable: false, configurable: false }
5.2 Object.getOwnPropertyDescriptor(obj, prop) [如果对象中存在该属性,则返回对应的属性描述符,否则返回 undefined]
Object.getOwnPropertyDescriptor() 静态方法返回一个对象,该对象描述给定对象上特定属性(即直接存在于对象上而不在对象的原型链中的属性)的配置。返回的对象是可变的,但对其进行更改不会影响原始属性的配置。
与 Object.getOwnPropertyDescriptor() 的不同点
- 如果该方法的第一个参数不是一个对象(一个原始值),那么将造成 [
TypeError]错误。而对于 [Object.getOwnPropertyDescriptor],非对象的第一个参数将被强制转换为一个对象处理。 - 无法返回不在对象的原型链中的属性配置
console.log(Reflect.getOwnPropertyDescriptor(obj, "name"));// {value: 'xingxing', writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj, "name"));// {value: 'xingxing', writable: true, enumerable: true, configurable: true}
console.log(Reflect.getOwnPropertyDescriptor("foo", 0)); // Uncaught TypeError: Reflect.getOwnPropertyDescriptor called on non-object
console.log(Object.getOwnPropertyDescriptor("foo", 0)); // {value: 'f', writable: false, enumerable: true, configurable: false}
console.log(Reflect.getOwnPropertyDescriptor([], 'length'));// { value: 0, writable: true, enumerable: false, configurable: false }
console.log(Object.getOwnPropertyDescriptor([], length)); // undefined