Proxy 对象简介

简介: 关于Vue3 中的数据响应式功能,我们大家应该都知道,它是通过 ES6的代理模式——Proxy 对象实现的,今天我们来简单认识下何为 Proxy 对象。

关于Vue3 中的数据响应式功能,我们大家应该都知道,它是通过 ES6的代理模式——Proxy 对象实现的,今天我们来简单认识下何为 Proxy 对象。


Proxy 的定义


Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。


proxy修改的是程序默认形为,就形同于在编程语言层面上做修改,属于元编程(metaprogramming),即对编程语言进行编程。


  • 元编程(英语:Metaprogramming,又译超编程,是指某类计算机程序的编写,这类计算机程序编写或者操纵其它程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作.


Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。


Proxy 的基本语法


ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。


var proxy = new Proxy(target, handler);


  • target:  要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
  • handler: 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 proxy 的行为。


Proxy 使用示例


下面是关于 Proxy 使用的一个基本示例:


const person = {
  name: "superMan",
};
const proxy = new Proxy(man, {
  get(target, property, receiver) {
    console.log(`正在获取 ${property} 属性`)
    return target[property];
  },
});
console.log(proxy.name);
console.log(proxy.age);


在以上示例中, Proxy 构造函数接受 person 对象为代理目标,创建了一个代理对象。在创建代理对象时,我们定义了一个 get 捕获器,用于捕获代理目标属性读取的操作。 捕获器的作用就是用于拦截用户对目标对象属性读取的相关操作,在这些操作传播到目标对象之前,会先调用对应的捕获器函数,从而拦截并修改相应的行为。


在设置了 get 捕获器之后,当成功运行以上的示例代码,控制台会输出以下结果:


正在获取 name 属性
superman
正在读取 age 属性
undefined


通过观察以上输出结果,我们可以发现 get 捕获器 不仅可以拦截已知属性的读取操作,也可以拦截未知属性的读取操作。


Proxy 实例当做原型对象


Proxy 实例也可以作为其他对象的原型对象:


var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});
let obj = Object.create(proxy);
obj.time  // 35


上面代码中,proxy对象是obj对象的原型,obj对象本身并没有time属性,所以根据原型链,会在proxy对象上读取该属性,导致被拦截。


Proxy 实例的方法


在创建 Proxy 对象时,除了定义 get 捕获器 之外,我们还可以定义其他的捕获器,比如 set、apply 、 has或者 deleteProperty  等。


get()


get方法用于拦截某个属性的读取操作,可以接受三个参数,依次为目标对象、属性名和 proxy 实例本身(严格地说,是操作行为所针对的对象),其中最后一个参数可选。


set()


set方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。


apply()


apply方法拦截函数的调用、callapply操作。


apply方法可以接受三个参数,分别是目标对象、目标对象的上下文对象(this)和目标对象的参数数组。


has()


has方法用来拦截HasProperty操作,即判断对象是否具有某个属性时,这个方法会生效。典型的操作就是in运算符。


has方法可以接受两个参数,分别是目标对象、需查询的属性名。


deleteProperty()


deleteProperty方法用于拦截delete操作,如果这个方法抛出错误或者返回false,当前属性就无法被delete命令删除。


defineProperty()


defineProperty方法拦截了Object.defineProperty操作。


总结


Proxy就是拦截层,你给出被拦截的对象,外界访问这个对象必须先通过拦截层,即访问Proxy的实例对象。通过Proxy为外界访问进行过滤和改写,如赋值时需满足某些条件。


学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!


知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!




相关文章
|
3月前
|
缓存 负载均衡 安全
|
2月前
|
缓存 监控 前端开发
Proxy对象有哪些应用场景
【9月更文挑战第3天】Proxy对象有哪些应用场景
45 4
|
5月前
es6 proxy的作用和用法
es6 proxy的作用和用法
27 5
|
6月前
es6中proxy如何使用
es6中proxy如何使用
73 0
ES6: Proxy概念及用法
ES6: Proxy概念及用法
61 0
玩转ES6(二)-Object.defineProperty和Proxy代理
玩转ES6(二)-Object.defineProperty和Proxy代理
96 0
|
前端开发
前端学习案例1-ES6中的proxy和Reflect
前端学习案例1-ES6中的proxy和Reflect
70 0
前端学习案例1-ES6中的proxy和Reflect
|
前端开发
前端学习案例2-ES6中的proxy和Reflect2
前端学习案例2-ES6中的proxy和Reflect2
76 0
前端学习案例2-ES6中的proxy和Reflect2
|
JavaScript 前端开发
【ES6】Proxy对象
【ES6】Proxy对象
113 0
es6 代理(Reflect)和反射(Proxy)的学习总结
es6 代理(Reflect)和反射(Proxy)的学习总结