每天3分钟,重学ES6-ES12(十九)Proxy-Reflect(一)

简介: 每天3分钟,重学ES6-ES12(十九)Proxy-Reflect

19c2e7a9bfbb7f5e8c7d744db995e29.png

每天3分钟,重学ES6-ES12文章汇总

监听对象的操作

  • 我们先来看一个需求:有一个对象,我们希望监听这个对象中的属性被设置或获取的过程
  • 通过我们前面所学的知识,能不能做到这一点呢?
  • 其实是可以的,我们可以通过之前的属性描述符中的存储属性描述符来做到;
  • 这段代码就利用了前面讲过的 Object.defineProperty 的存储属性描述符来对 属性的操作进行监听。
const obj = {
  name: "why",
  age: 18
}
Object.defineProperty(obj, "name", {
   get: function() {
     console.log("监听到obj对象的name属性被访问了")
   },
   set: function() {
     console.log("监听到obj对象的name属性被设置值")
   }
})
  • 但是这样做有什么缺点呢?
  • 首先,Object.defineProperty设计的初衷,不是为了去监听截止一个对象中所有的属性的。
  • 我们在定义某些属性的时候,初衷其实是定义普通的属性,但是后面我们强 行将它变成了数据属性描述符。
  • 其次,如果我们想监听更加丰富的操作,比如新增属性、删除属性,那么 Object.defineProperty是无能为力的。
  • 所以我们要知道,存储数据描述符设计的初衷并不是为了去监听一个完整的对象。

Proxy基本使用

  • 在ES6中,新增了一个Proxy类,这个类从名字就可以看出来,是用于帮助我们创建一个代理的:
  • 也就是说,如果我们希望监听一个对象的相关操作,那么我们可以先创建一个代理对象(Proxy对象);
  • 之后对该对象的所有操作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行哪些操作;
  • 我们可以将上面的案例用Proxy来实现一次:
  • 首先,我们需要new Proxy对象,并且传入需要侦听的对象以及一个处理对象,可以称之为handler;
  • const p = new Proxy(target, handler)
  • 其次,我们之后的操作都是直接对Proxy的操作,而不是原有的对象,因为我们需要在handler里面进行侦听;

Proxy的set和get捕获器

  • 如果我们想要侦听某些具体的操作,那么就可以在handler中添加对应的捕捉器(Trap):
  • set和get分别对应的是函数类型;
  • set函数有四个参数:
  • target:目标对象(侦听的对象);
  • property:将被设置的属性key;
  • value:新属性值;
  • receiver:调用的代理对象;
  • get函数有三个参数:
  • target:目标对象(侦听的对象);
  • property:被获取的属性key;
  • receiver:调用的代理对象;

代码展示

const obj = {
  name: "why",
  age: 18
}
const objProxy = new Proxy(obj, {
  // 获取值时的捕获器
  get: function(target, key) {
    console.log(`监听到对象的${key}属性被访问了`, target)
    return target[key]
  },
  // 设置值时的捕获器
  set: function(target, key, newValue) {
    console.log(`监听到对象的${key}属性被设置值`, target)
    target[key] = newValue
  }
})

Proxy所有捕获器

  • 13个捕捉器分别是做什么的呢?
handler.getPrototypeOf()
    Object.getPrototypeOf 方法的捕捉器。
handler.setPrototypeOf()
    Object.setPrototypeOf 方法的捕捉器。
handler.isExtensible()
    Object.isExtensible 方法的捕捉器。
handler.preventExtensions()
    Object.preventExtensions 方法的捕捉器。
handler.getOwnPropertyDescriptor()
    Object.getOwnPropertyDescriptor 方法的捕捉器。
handler.defineProperty()
    Object.defineProperty 方法的捕捉器。
handler.ownKeys()
    Object.getOwnPropertyNames 方法和Object.getOwnPropertySymbols 方法的捕捉器。
handler.has()
    in 操作符的捕捉器。
handler.get()
    属性读取操作的捕捉器。
handler.set()
    属性设置操作的捕捉器。
handler.deleteProperty() 
    delete 操作符的捕捉器。
handler.apply()
    函数调用操作的捕捉器。
handler.construct()
    new 操作符的捕捉器。

Proxy的construct和apply

当然,我们还会看到捕捉器中还有construct和apply,它们是应用于函数对象的:

function foo() {
}
const fooProxy = new Proxy(foo, {
  apply: function(target, thisArg, argArray) {
    console.log("对foo函数进行了apply调用")
    return target.apply(thisArg, argArray)
  },
  construct: function(target, argArray, newTarget) {
    console.log("对foo函数进行了new调用")
    return new target(...argArray)
  }
})
fooProxy.apply({}, ["abc", "cba"])
new fooProxy("abc", "cba")


相关文章
|
存储 安全 JavaScript
【分布式技术专题】「授权认证体系」深度解析OAuth2.0协议的原理和流程框架实现指南(授权流程和模式)
在传统的客户端-服务器身份验证模式中,客户端请求服务器上访问受限的资源(受保护的资源)时,需要使用资源所有者的凭据在服务器上进行身份验证。资源所有者为了给第三方应用提供受限资源的访问权限,需要与第三方共享它的凭据。这就导致一些问题和局限:
830 2
【分布式技术专题】「授权认证体系」深度解析OAuth2.0协议的原理和流程框架实现指南(授权流程和模式)
|
JSON 自然语言处理 前端开发
用D3制作一张有翻页特效的手撕日历(只需100行代码)
在D3中用十分简单的代码就可以实现丰富的动画,下面来看一下手撕日历的动画效果吧
533 1
用D3制作一张有翻页特效的手撕日历(只需100行代码)
|
开发框架 小程序 前端开发
小程序全栈开发中的跨平台解决方案
【4月更文挑战第12天】本文探讨了小程序全栈开发中的跨平台问题,包括前端、后端和数据交互差异,并提出了解决方案:使用跨平台框架(如Taro、uni-app)、设计统一后端接口、创建API适配层以及利用云开发平台。这些方法旨在帮助开发者提高效率,实现一次开发多平台运行。随着技术进步,预计会有更多便捷的跨平台工具出现。
413 0
拥抱不确定性:在技术世界中平衡创新与稳定性
【4月更文挑战第8天】 在快速迭代的技术领域,创新与稳定性之间的拉锯战不断上演。本文探讨了如何在追求前沿技术的同时维持系统的稳定性和可靠性。通过分析技术创新的风险与回报,提出一种平衡策略,旨在帮助技术决策者在不断变化的环境中找到合适的发展路径。
285 0
|
Linux
【ARM】迅为rk3568开发板buildroot添加桌面应用
【ARM】迅为rk3568开发板buildroot添加桌面应用
487 0
|
存储 安全 数据安全/隐私保护
DP读书:鲲鹏处理器 架构与编程(九)鲲鹏920处理器片上系统
DP读书:鲲鹏处理器 架构与编程(九)鲲鹏920处理器片上系统
728 0
|
存储 C语言
C语言 关于输入输出与结束符“\0”
C语言 关于输入输出与结束符“\0”
931 1
|
监控 数据可视化 数据挖掘
数据可视化第二版-拓展-和鲸网约车分析一等奖作品
数据可视化第二版-拓展-和鲸网约车分析一等奖作品
uniapp生成所设置字符串的条形码
uniapp生成所设置字符串的条形码
425 0
|
存储 监控 数据可视化
这10款看板软件,让项目管理更有条理!
10个看板工具推荐,项目管理必备!