什么是 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 上,至于难度完全没看到!