- A+
Reflect的作用
一开始学习Reflect的时候其实觉得很迷惑,感觉通过Reflect操作Proxy对象或者Object对象总有一种多此一举的感觉。
为什么要使用Reflect操作对象,而不是直接在Proxy和Object上做操作呢?
原因之一是:Proxy和Object相关的API和操作方式在早期设计得不合理,不规范。但是Proxy和Object又是属于比较底层的东西,破坏性的改动会影响到非常多的现有代码。Reflect的提出就是为了解决这个问题,提供了一套现代的、规范的API来操作对象。
Reflect的优点可以由下面几点体现出来:
-
在对象上定义属性失败时:
Object.defineProperty(obj, name, desc)
直接抛出异常,而Reflect.defineProperty(obj, name, desc)
则是返回false
。 -
将部分命令式的
Object
操作规范化为函数行为:name in obj
变为:Reflect.has(obj, name)
;delete obj[name]
变为:Reflect.deleteProperty(obj, name)
;
-
Reflect简化了一些操作:
// 老写法 Function.prototype.apply.call(Math.floor, undefined, [1.75]) // 1 // 新写法 Reflect.apply(Math.floor, undefined, [1.75]) // 1
静态方法
-
调用函数:Reflect.apply(target, thisArg, args)
-
调用构造函数:Reflect.construct(target, args)
-
读属性:Reflect.get(target, name, receiver)
-
写属性:Reflect.set(target, name, value, receiver)
-
定义属性:Reflect.defineProperty(target, name, desc)
-
删除属性:Reflect.deleteProperty(target, name)
-
查询属性是否存在:Reflect.has(target, name)
-
对象所有属性:Reflect.ownKeys(target)
等于
Object.getOwnPropertyNames
和Object.getOwnPropertySymbols
。 -
对象是否可扩展:Reflect.isExtensible(target)
-
让一个对象不可扩展:Reflect.preventExtensions(target)
-
获取属性的描述对象:Reflect.getOwnPropertyDescriptor(target, name)
-
获取对象的原型对象:Reflect.getPrototypeOf(target)
-
设置对象的原型对象:Reflect.setPrototypeOf(target, prototype)
使用Proxy实现观察者模式
// 创建一个集合来保存观察者函数 const observers = new Set(); // 函数:添加新的观察者函数到观察者集合中 function observe(fn){ observers.add(fn); } // 函数:创建一个可观察的对象 function observable(target){ // 返回一个代理来拦截对目标对象的修改 return new Proxy(target, { set(target, name, value, receiver){ // 设置目标对象上的属性 const result = Reflect.set(target, name, value, receiver); // 通知所有观察者函数属性的变化 notify(); return result; } }); } // 函数:通知所有观察者函数属性的变化 function notify(){ // 调用观察者集合中的每一个观察者函数 observers.forEach(fn => fn()); } // ================================================================= // 测试部分 // 创建一个包含count属性的可观察对象 let state = observable({ count: 1, }); // 添加一个观察者函数,每次state的count属性更新时,都会在控制台输出日志 observe(() => { console.log('state update: ', state.count); }); // 多次递增state的count属性 state.count++; state.count++; state.count++;
输出结果:
state update: 2 state update: 3 state update: 4