ES6 Reflect反射
概述
Reflect 是 ES6 为了操作对象引入的 API 。
Reflect 可以用于获取目标对象的行为,它与 Object 类似,它的方法与 Proxy 是对应的。
基本用法:
1、Reflect.get(target, name, receiver) 查找并返回 target 对象的 name 属性。
let exam = {
name: "Tom",
age: 24,
get info(){
return this.name + this.age;
}
}
Reflect.get(exam, 'name'); // "Tom"
// 当 target对象中存在属性的getter方法, getter方法的this会绑定 receiver
let receiver = {
name: "Jerry",
age: 20
}
Reflect.get(exam, 'info', receiver); // Jerry20
2、Reflect.set(target, name, value, receiver) 返回boolean类型
let exam = {
name: "Tom",
age: 24,
set info(value){
return this.age = value;
}
}
exam.age; // 24
Reflect.set(exam, 'age', 25); // true
console.log(exam.age); // 25
let receiver = {//当 target对象中存在属性setter方法时,setter方法中的this会绑定receiver
age: 18
}
Reflect.set(exam, 'info', 1, receiver); // true
receiver.age; // 1
3、Reflect.has(obj, name) 是 name in obj 指令的函数化,用于查找 name 属性在 obj 对象中是否存在。
……
组合使用(Reflect与Proxy)
Reflect 对象的方法与 Proxy 对象的方法是一一对应的。所以 Proxy 对象的方法可以通过调用 Reflect 对象的方法获取默认行为,然后进行额外操作。
let exam = { name: "Tom", age: 24 } let handler = { get: function(target, key){ return Reflect.get(target,key); }, set: function(target, key, value){ Reflect.set(target, key, value); } } let proxy = new Proxy(exam, handler) proxy.name = "Jerry" proxy.name // "Jerry"
比对下:上面的get方法等同于下面的方法。
get(target, propKey, receiver) { return target[propKey]; //这边用Reflect.get(target,key)替换,结果一样。
}
观察者模式 Observer
当一个对象被修改时,则会自动通知它的依赖对象。
// 定义 Set 集合 const queuedObservers = new Set(); // 把观察者函数都放入 Set 集合中 const observe = fn => queuedObservers.add(fn); // observable 返回原始对象的代理,拦截赋值操作 const observable = obj => new Proxy(obj, {set}); function set(target, key, value, receiver) { // 获取对象的赋值操作 const result = Reflect.set(target, key, value, receiver); // 执行所有观察者 queuedObservers.forEach(observer => observer()); // 执行赋值操作 return result; }
const person = observable({ name: '张三', age: 20 }); function print() { console.log(`person的姓名更改为${person.name}`); //`${}`是es6中新增的字符串方法,用来替换字符串用的,在字符串中引入变量。 } observe(print);//当person的属性变动时,自动通知print去打印信息。(Observer模式) person.name = '李四'; // person的姓名更改为李四