什么是Reflect?
ES6 为了操作对象而提供的新API,未来的新方法将只部署在Reflect对象上!
初探Reflect
Reflect与Proxy是相辅相成的,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法!
const obj = { name: "song" };
const proxy = new Proxy(obj, {
get(target, name) {
// reflect保证原生行为能够正常执行
return Reflect.get(target, name);
},
set(target, name, value) {
return Reflect.set(target, name, value);
},
has(target, name) {
// 通过in操作符会调用has方法
return Reflect.has(target, name);
}
});
// reflect 将原有的命令式 都转化为函数行为
console.log("name" in proxy);
console.log(Reflect.has(proxy, "name")); // 也可以直接通过Reflect来判断
Reflect静态方法
Reflect对象一共有 13 个静态方法。我们依次用老写法和新写法做对比!
1.Reflect.get
获取对象中对应key的值
const my = {
name:'song',
age:18,
get mny(){
return this.a + this.b
}
}
console.log(my['age']); // 老写法
console.log(Reflect.get(my,'age'));
console.log(Reflect.get(my,'mny',{a:1,b:2})); // 可以指定this指向
2.Reflect.set
设置对象中key对应的值
const my = {
name: "song",
age: 18,
set mny(val) {
this.value = val;
}
};
let mny = { value: 0 };
my.mny = 100; // 老写法
Reflect.set(my, "mny", 100);
Reflect.set(my, "mny", 100, mny); // 给对象设置属性,并且传递this
console.log(mny); // {value:100}
3.Reflect.has
判断某个key是否属于这个对象
const my = {
name:'song'
}
console.log('name' in my);
console.log(Reflect.has(my,'name'));
4.Reflect.defineProperty
定义对象的属性和值,等价于Object.defineProperty
const person = {};
Object.defineProperty(person,'name',{
configurable:false,
value:'song'
});
console.log(person.name); // 老写法,后续会被废弃
Reflect.defineProperty(person,'name',{
configurable:false,
value:'song'
})
console.log(person.name);
5.Reflect.deleteProperty
删除对象中某个属性
const person = {};
Reflect.defineProperty(person,'name',{
configurable:false,
value:'song'
});
// delete person.name; 无返回值
const flag = Reflect.deleteProperty(person,'name');
console.log(flag); // 返回是否删除成功
6.Reflect.construct
实例化类,等价于new
class Person{
constructor(sex){
console.log(sex);
}
}
new Person('女'); // 老写法
Reflect.construct(Person,['男']);
7.Reflect.getPrototypeOf
读取proto,等价于Object.getPrototypeOf,不同的是如果方法传递的不是对象会报错!
class Person {}
// 老写法
console.log(Object.getPrototypeOf(Person) === Reflect.getPrototypeOf(Person));
8.Reflect.setPrototypeOf
设置proto,等价于Object.setPrototypeOf,不同的是返回一个boolean类型表示是否设置成功!
let person = {name:'song'};
let obj = {age:18};
// Object.setPrototypeOf(person,obj); // 老写法
Reflect.setPrototypeOf(person,obj);
console.log(person.age);
9.Reflect.apply
想必apply方法大家都很了解了, Reflect.apply 等价于Function.prototype.apply.call
const func = function(a,b){
console.log(this,a,b);
}
func.apply = () =>{
console.log('apply')
}
// func.apply({name:'song'},[1,2]); // 调用的是自己身上的方法
Function.prototype.apply.call(func,{name:'song'},[1,2]); // 老写法
Reflect.apply(func,{name:'song'},[1,2]); // 是不是非常的简单!
10.Reflect.getOwnPropertyDescriptor
等价于Object.getOwnPropertyDescriptor,获取属性描述对象
const obj = {name:1};
// const descriptor = Object.getOwnPropertyDescriptor(obj,'name'); // 老写法
const descriptor = Reflect.getOwnPropertyDescriptor(obj,'name');
console.log(descriptor);
11.Reflect.preventExtensions
让一个对象变的不可扩展,也就是永远不能再添加新的属性,等价于 Object.preventExtensions
const person = {};
// 旧写法
Object.preventExtensions(person); // 设置对象不可扩展
Reflect.preventExtensions(person);
person.a = 1;
console.log(person.a); // undefined
12.Reflect.isExtensible
表示当前对象是否可扩展,等价于Object.isExtensible
const person = {};
Reflect.preventExtensions(person);
Object.isExtensible(person) // 老写法 false
Reflect.isExtensible(person) // false
13.Reflect.ownKeys
用于返回对象的所有属性,包括Symbol属性
const person = {
age:18,
[Symbol('name')]:'song'
};
console.log(Object.getOwnPropertyNames(person)); // [ 'age' ] 老写法
console.log(Object.getOwnPropertySymbols(person)); // [ Symbol(name) ] 老写法
console.log(Reflect.ownKeys(person)); // [ 'age', Symbol(name) ]
到此我们把Reflect的所有用法已经讲解完毕,内容比较干!其实核心就是将原有的Object的部分方法放到了Reflect上,至于难度完全没看到!