写点什么

Proxy 对象简介

用户头像
编程三昧
关注
发布于: 2021 年 06 月 06 日
Proxy 对象简介

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

Proxy 的定义

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


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


  • 元编程(英语: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 为外界访问进行过滤和改写,如赋值时需满足某些条件。


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

大家好!我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!

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

发布于: 2021 年 06 月 06 日阅读数: 8
用户头像

编程三昧

关注

学习有趣的知识,塑造有趣的灵魂! 2019.08.30 加入

还未添加个人简介

评论

发布
暂无评论
Proxy 对象简介