Reflect对象是一个全局的普通的对象。Reflect的原型就是Object.
Reflect对象和Object对象的区别
- Reflect:是javaScript的内置对象,它不是一个函数对象,不可构造,即不可以和new一起用,所提供的方法都是静态方法;
- Object:是JavaScript的内置对象,它是个构造函数,以new Object()的形式被调用,所提供的方法有静态方法(构造函数方法)和原型方法;
- 在使用对象的
Object.defineProperty(obj, name, {})
时,如果出现异常的话,会抛出一个错误,需要使用try catch
去捕获,但是使用Reflect.defineProperty(obj, name, desc)
则会返回false。
try {
Object.defineProperty(target, property, attributes);
} catch(e) {
// 失败
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
Reflect.get(target, name, receiver)
该方法是用来读取一个对象的属性。
参数如下解析:
target: 目标对象
name: 是我们要读取的属性。
receiver(可选): 可以理解为上下文this对象。
const obj = {
name: 'huhao',
age: 30,
get xxx() {
console.log(this.name);
console.log('-------');
}
};
console.log(Reflect.get(obj, 'name')); // huhao
console.log(Reflect.get(obj, 'xxx')); // undefined
/*
先执行 xxx 方法 打印 huhao 和 ----,
然后在打印undefined, 因为该xxx()函数没有返回值
*/
console.log(Reflect.get(obj, 'xxx'));
/*
会执行 xxx() 方法,打印 happy, 因此第三个参数指向上下文
就指向了这个对象,然后打印 ----- ,最后打印undefined
因为该函数没有返回值
*/
console.log(Reflect.get(obj, 'xxx', {name: 'happy'}));
/*
会执行 xxx() 方法,打印 undefined, 因此第三个参数指向上下文
就指向了这个对象,而这个对象里面又没有name属性,因此会打印undefined
然后打印 ----- ,最后打印undefined. 因为该函数没有返回值
*/
console.log(Reflect.get(obj, 'xxx', {age: 'happy'}));
const obj2 = {
name: 'huhao2',
age: 30,
get xxx() {
console.log(this.name);
console.log('----xxxx---');
return 0;
}
};
/*
先执行 obj2 该对象中的 xxx 方法,指定了第三个参数作为该上下文对象,
因此会打印 happy2, 然后继续打印 ----xxxx---, 最后我们可以看到
有返回值为0,因此打印0了
*/
console.log(Reflect.get(obj2, 'xxx', {name: 'happy2'}));
Reflect.set(target,name,value,receiver)
上面的get方法是获取对象中的值,那么set就是设置该对象的属性值了,参数解析简单如下:
target: 我们需要操作的对象。
name: 我们需要设置该对象的属性名。
value: 我们要设置的属性值。
receiver: 可以理解为上下文this对象。如果我们在设置值的时候遇到setter函数,该参数就指向与setter中上下文this对象。
该函数会返回一个Boolean的值,代表在目标对象上设置属性是否成功。
const obj = {
age: 30,
set name(name) {
console.log(this);
console.log('-------');
}
};
const res = Reflect.set(obj, 'age', 31);
console.log(res); // true
console.log(obj); // {age: 31, set name:function} 这样的
console.log(obj.age); // 打印 31
/*
如下代码,设置 obj对象中的name属性,因此打印 console.log(this)
返回 {age: 31, set name:function} 这样的, console.log(res2)返回true,设置成功
*/
const res2 = Reflect.set(obj, 'name', 'xxxx');
console.log(res2); // true
/*
先执行 set 中的name方法,打印 console.log(this);this就指向了第四个参数 {test: 'test'}
然后会打印 '-----';
*/
const r2 = Reflect.set(obj, 'name', 'dreamapple', {test: 'test'}); // this: --> { test: 'test' }
console.log(r2); // true
console.log(obj); // { name: [Setter], age: 31 }
Reflect.apply(target,thisArg,args)(了解)
该方法的含义是:通过指定的参数列表对该目标函数的调用。该方法类似于我们之前的 Function.prototype.apply 方法的。
参数解析如下:
target: 我们的目标函数.
thisArg: target函数调用的时候绑定的this对象。
args: 就是函数参数列表。
Reflect.construct(target,args[, newTarget])(了解)
该方法的作用和 new AAA() 创建一个实列方法作用类似,那么使用该方法,我们就可以提供一种不使用new来调用构造函数的方法,
参数含义如下:
target: 被运行的目标函数。
args: 调用构造函数传递的参数数组或伪数组。
newTarget: 也是构造函数,表示使用 Reflect.construct后生成的实列对象是谁的实列。如果没有该参数,默认生成的实列对象就和target构造函数是一样的。
Reflect.defineProperty(target,name,desc)
该方法与Object.defineProperty方法类似的,不过唯一的区别是 Reflect.defineProperty返回值是一个Boolean的值。
const obj = {};
// 使用 Object.defineProperty
try {
Object.defineProperty(obj, 'a', {
value: 22
})
} catch(e) {
console.log('define property failed');
}
// 使用 Reflect.defineProperty
const res = Reflect.defineProperty(obj, 'b', {
configurable: true,
enumerable: true
});
console.log(res); // true
Reflect.deleteProperty(target,name)
该方法用于删除一个对象上的属性,它和delete操作符类似的。
参数如下:
target: 表示要操作的对象。
name: 表示要删除该对象上的属性。
该函数返回值是一个Boolean的值,如果成功的话,返回true,失败的话返回false。
const obj = {
name: 'huhao',
age: 30
};
let test1 = Reflect.deleteProperty(obj, 'name');
console.log(test1); // true
console.log(obj); // {age: 30}
// 如果删除对象上不存在的属性的话,也是返回true的
let test2 = Reflect.deleteProperty(obj, 'xx');
console.log(test2); // true
console.log(obj); // {age: 30}
let test3 = Reflect.deleteProperty(obj, 'age');
console.log(test3); // true
console.log(obj); // {}
Reflect.has(target,name)
该方法的含义是:检查一个对象上是否含有特定的属性。相当于es5中的in操作符。
那么参数 target: 就是改对象哦,name的含义是:该对象上的属性。
// 一般的对象
const obj = {
name: 'huhao',
age: 30
};
console.log(Reflect.has(obj, 'name')); // true
console.log(Reflect.has(obj, 'username')); // 该对象上没有 username属性 返回false
console.log(Reflect.has(obj, 'age')); // true
// 函数的实列
function Obj(name) {
this.name = name;
}
Obj.prototype.getName = function() {
return this.name;
}
const test = new Obj();
// 使用in操作符测试
console.log('name' in test); // true
console.log('getName' in test); // true
// 使用Reflect.has 测试
console.log(Reflect.has(test, 'name')); // true
console.log(Reflect.has(test, 'getName')); // true
Reflect.ownKeys(target)
该函数的作用是:返回由目标对象自身的属性键组成的数组。如果这个目标对象不是一个对象的话,那么该函数就会抛出一个异常。
target参数:它是一个对象。
//Object.keys()
const obj1 = {
name: 'huhao',
age: 30
};
console.log(Object.keys(obj1)); // ['name', 'age'];
//Reflect.ownKeys
const obj2 = {
name: 'huhao',
age: 30
};
console.log(Reflect.ownKeys(obj2)); // ['name', 'age'];
Reflect.preventExtensions(target)
该方法的作用是 阻止新的属性添加到对象中去。target参数必须是一个对象,否则的话会抛出一个异常。
const obj = {};
// 判断该对象是否可以扩展,使用 Reflect.isExtensible 该方法
const t1 = Reflect.isExtensible(obj);
console.log(t1); // true
// 使用 Reflect.preventExtensions 来阻止该对象扩展
Reflect.preventExtensions(obj);
// 再来扩展下该对象,看是否可以
const t2 = Reflect.isExtensible(obj);
console.log(t2); // false
Reflect.isExtensible(target)
该方法的作用是检查一个对象是否可以扩展的,也就是说对象里面是否可以添加新的属性或方法。
target参数表示目标对象。如果该目标对象不是一个对象的话,那么函数会抛出一个异常。
该函数会返回一个Boolean值,如果为true的话,说明该对象可以扩展,否则的话返回false,表示该对象不可以扩展。
const obj = {};
// 判断该对象是否可以扩展,使用 Reflect.isExtensible 该方法
const t1 = Reflect.isExtensible(obj);
console.log(t1); // true
// 使用 Reflect.preventExtensions 来阻止该对象扩展
Reflect.preventExtensions(obj);
// 再来扩展下该对象,看是否可以
const t2 = Reflect.isExtensible(obj);
console.log(t2); // false
Reflect.getOwnPropertyDescriptor(target, name)
该方法的参数如下解析:
target: 表示的是目标对象。
name: 表示目标对象的属性
该方法的具体含义是:如果目标对象中的属性描述符存在的话,就返回这个属性描述符,如果不存在,就返回undefined。
const obj = {};
Reflect.defineProperty(obj, 'name', {
configurable: true,
enumerable: true,
writable: true,
value: '30'
});
const test1 = Reflect.getOwnPropertyDescriptor(obj, 'name');
/*
打印值如下:
{
configurable: true
enumerable: true
value: "30"
writable: true
}
*/
console.log(test1);
const test2 = Reflect.getOwnPropertyDescriptor(obj, 'age');
console.log(test2); // undefined
// 如果第一个参数不是对象
const test3 = Object.getOwnPropertyDescriptor('kkkk', 'name');
console.log(test3); // undefined
// 使用 try catch 包围,会执行 catch方法内部代码
try {
const test4 = Reflect.getOwnPropertyDescriptor('kkkk', 'name');
console.log(test4);
} catch (e) {
console.log('error');
}
Reflect.getPrototypeOf(target)
该方法是返回一个对象的原型的,也就是说内部的 [[Prototype]] 属性的值。来看如下代码:
function testA() {};
testA.prototype.xxx = function() {};
const a = new testA();
console.log(Object.getPrototypeOf(a));
结果输出
Reflect.setPrototypeOf(target, prototype)
该方法的作用是设置一个对象的原型。如果设置成功的话,这个对象就返回一个true,如果设置失败的话,这个对象就返回一个false。
const obj = {};
const test1 = Reflect.setPrototypeOf(obj, Object.prototype);
console.log(test1); // true
let test2 = Reflect.setPrototypeOf(Object.freeze({}), null);
console.log(test2); // false