ES6 Proxy与Reflect详解:原理、用法及观察者模式实现

作者:闭包旅人

时间:2026-10-23

浏览:595

本文深入解析ES6新增的Proxy和Reflect API。Proxy用于修改对象操作的默认行为,实现元编程;Reflect则提供与Proxy一一对应的静态方法,使对象操作函数化并减少异常抛出。文章通过代码实例展示了如何利用Proxy的set拦截器和Reflect.set实现简单的观察者模式,帮助开发者理解二者在JavaScript对象操作中的核心联系与应用。

文章目录

本文通过具体实例,详细阐述了ES6中Proxy和Reflect的使用方法及应用场景,旨在为读者提供参考。

Proxy和Reflect是ES6标准中为优化对象操作而引入的新API。下文将深入探讨这两者的具体作用及其内在联系。

首先分析设计Proxy和Reflect的核心目的:

Proxy的主要作用在于:

Proxy的设计初衷是(修改编程语言)的默认行为,即修改某些特定操作方法的默认执行逻辑。

这相当于在语言层面进行了修改,属于元编程(meta programming)的范畴。例如,通过Proxy可以自定义修改set和get方法的默认行为。

Reflect的主要作用包括:

1,映射一些明显属于对象语言内部的方法。目前这些方法共存于Object和Reflect上,未来可能仅保留在Reflect上。

2,修改一些Object上方法返回的结果,通过减少异常抛出使行为更加合理。

3,让Object操作都转变为函数行为(这是其主要作用之一)。

4,确保Reflect对象的方法与Proxy对象的方法能够一一对应(这也是其主要作用之一)。

接下来具体介绍Proxy和Reflect的具体方法:

Proxy的实例方法包括:

get() set() apply() has() cunstruct() deleteProperty() defineProperty()
getOwnPropertyDescriptor() getPrototypeOf() isExtensible() ownKeys(), preventExtensions() setPrototypeOf()  

var person = {
 name: "张三"
};
 
var proxy = new Proxy(person, {
 get: function(target, property) {
  if (property in target) {
   return target[property];
  } else {
   throw new ReferenceError("Property \"" + property + "\" does not exist.");
  }
 }
});

注意:目标对象内部的this关键字会指向Proxy代理对象。

自身方法:Proxy.revocable方法返回一个可取消的Proxy实例。

Reflect的静态方法包括:

与Proxy相对应,Reflect提供了13个静态方法,它们分别一一对应于Proxy的实例方法。

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)
Reflect.isExtensible(target) Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name) Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)  

Proxy和Reflect的联系:Proxy的实例方法和Reflect的静态方法存在一一对应关系。

实例:利用Proxy和Reflect实现观察者模式。


const queuedObservers = new Set();
 
const observe = fn => queuedObservers.add(fn);//接收一个函数fn
const observable = obj => new Proxy(obj, {set});//接收一个对象obj,采用set函数拦截设置obj
 
function set(target, key, value, receiver) {
 const result = Reflect.set(target, key, value, receiver);
 queuedObservers.forEach(observer => observer());
 return result;
}

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《JavaScript操作DOM技巧总结》、《JavaScript页面元素操作技巧总结》、《JavaScript事件相关操作与技巧大全》、《JavaScript查找算法技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章