Proxy和definedProperty

1. Proxy 代理

定义: 用于定义基本操作的自定义行为

Proxy修改的是程序默认形为,就形同于在编程语言层面上做修改,属于元编程

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

元编程优点 与手工编写全部代码相比,程序员可以获得更高的工作效率,或者给与程序更大的灵活度去处理新的情形而无需重新编译

大概意思就是 我给你封装了一层,在我操作你的中间加了一段路径,可以用来处理,监听,截停等操作,简称拦路虎

 Proxy 译为代理,可以理解为在操作目标对象前架设一层代理,将所有本该我们手动编写的程序交由代理来处理,生活中也有许许多多的“proxy”, 如代购,中介,因为他们所有的行为都不会直接触达到目标对象

2. Proxy的使用

let p = new Proxy(target, handler);

target:用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数。

let yu = { age: 19, height: 155 }
let p = new Proxy(yu, {
    get: (target, property) => {
        if (property === 'age') {
            return target.age + 6
        } else if (property === 'height') {
            return target.height * 2
        }
     }
})

p.age // 25
yu.age // 19

p.height // 310
yu.height // 155

 

2.1 Handler 对象常用的方法

handler.get上面已经用过了,它其实接受三个参数 get(target, propKey, ?receiver)

  • target 目标对象
  • propkey 属性名
  • receiver Proxy 实例本身

其他的都大同小异,差不多

2.2 可撤消的Proxy

proxy有一个唯一的静态方法 ------- proxy.revocable(target, handler)

这个方法可以用来创建一个可撤销的代理对象
该方法的返回值是一个对象,其结构为: { “proxy”: proxy,“revoke”: revoke }

  1. proxy 表示新生成的代理对象本身,和用一般方式 new Proxy(target, handler) 创建的代理对象没什么不同,只是它可以被撤销掉
  2. revoke 撤销方法,调用的时候不需要加任何参数,就可以撤销掉和它一起生成的那个代理对象
const target = { name: 'yu'}
const {proxy, revoke} = Proxy.revocable(target, handler)
proxy.name // 正常取值输出 vuejs
revoke() // 取值完成对proxy进行封闭,撤消代理
proxy.name // TypeError: Revoked

3. proxy和Object.defineProperty

在proxy之前,vue2用的是Object.defineProperty,允许对对象的setter/getter进行拦截,Vue3.0之前的双向绑定是由defineProperty实现的,在3.0重构为 Proxy,那么两者的区别究竟在哪里呢?

定义: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

上面给两个词划了重点,对象上属性,我们可以理解为是针对对象上的某一个属性做处理的

语法:

Object.defineProperty(obj, prop, descriptor)
 

- obj 要定义属性的对象
prop 要定义或修改的属性的名称或 Symbol

- descriptor 要定义或修改的属性描述符

const obj = {}
Object.defineProperty(obj, "a", {
  value : 1,
  writable : false, // 是否可写 
  configurable : false, // 是否可配置
  enumerable : false // 是否可枚举
})

// 上面给了三个false, 下面的相关操作就很容易理解了
obj.a = 2 // 无效
delete obj.a // 无效
for(key in obj){
  console.log(key) // 无效 
}

3.1 Vue2中的defineProperty

Vue2的双向绑定都是通过 defineProperty 的 getter,setter 来实现的

const obj = {};
Object.defineProperty(obj, 'a', {
  set(val) {
    console.log(`开始设置新值: ${val}`)
  },
  get() { 
    console.log(`开始读取属性`)
    return 1; 
  },
  writable : true
})

obj.a = 2 // 开始设置新值: 2
obj.a // 开始获取属性 

3.2 defineProperty的缺点

Vue在初始化时会对data对象的属性进行数据劫持,但是对于后续新增的属性,Vue无法自动进行响应式处理。Vue 无法探测普通的新增属性

对象

这也就是为什么对象的新增属性为什么不更新

data  () {
  return  {
    obj: {
      a: 1
    }
  }
}

methods: {
  update () {
    this.obj.b = 2
  }
}

这个其实很好理解,我们先要明白 vue 中 data init 的时机,data init 是在生命周期 created 之前的操作,会对 data 绑定一个观察者 Observer,之后 data 中的字段更新都会通知依赖收集器Dep触发视图更新

然后我们回到 defineProperty 本身,是对对象上的属性做操作,而非对象本身

一句话来说就是,在 Observer data 时,新增属性并不存在,自然就不会有 getter, setter,也就解释了为什么新增视图不更新,解决有很多种,Vue 提供的全局$set 本质也是给新增的属性手动 observer

利用delete删除对象的属性,无法被Vue监测到

数组

还有一个就是数组了,由于 JavaScript 的限制,Vue 不能检测以下数组的变动:数组索引设置或者长度改变不是响应式的

var vm = new Vue({
  data: {
    items: ['1', '2', '3']
  }
})
vm.items[1] = '4' // 视图并未更新

解决方法:使用数组的 push()pop()shift()unshift()splice()sort()reverse() 方法来确保数组的变化是响应式的

3.3 总的来说

  • Object.definedProperty 是劫持对象的属性,新增元素需要再次 definedProperty。而 Proxy 劫持的是整个对象,不需要做特殊处理

  • 使用 defineProperty 时,我们修改原来的 obj 对象就可以触发拦截,而使用 proxy,就必须修改代理对象,即 Proxy 的实例才可以触发拦截

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/720329.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Profibus协议转Modbus协议网关模块帮助PLC实现智能激光设备通讯

一、前言 Profibus转Modbus网关(XD-MDPB100)是一种工业通信协议转换设备,用于实现Profibus协议与Modbus协议之间的转换。Profibus转Modbus网关在工业自动化系统中具有广泛的应用,它解决了不同协议设备之间的通信问题。本文将深入…

STM32单片机-通信协议(下)

STM32单片机-通信协议(下) 一、通信协议介绍二、USART(通用同步/异步收发器)2.1 USART框图和基本结构2.2 串口发送2.2.1 Printf函数移植2.2.2 串口发送汉字 2.3 串口接收2.3.1 串口接收查询2.3.2 串口接收中断 2.4 USART串口数据包2.4.1 数据包格式2.4.2 数据包接收…

经验分享:申请贷款的时候会被查大数据信用吗?

当我们考虑申请贷款时,往往会关注到背后的信用评估机制。这个过程中,大数据的使用日益成为一个关键因素。所谓大数据信用查询并不仅仅是传统的信用报告查询,它涵盖了更广泛的数据范围和更复杂的分析方法,以全面评估申请人的信用状…

2024年文献数据库合集分享

无论是刚踏入学术界的新手,还是经验丰富的资深学者,在寻找专业资料时都可能感到头疼:这些资料太专业了,普通网站难以找到... 许多人可能都有过这样的经历:急需一篇论文,却发现只有海外的专业网站才有&#…

软件测试过程中用接口怎么将web系统的多页数据展示在1页

例如:需要搜10页数据,用接口去处理 第一步:去搜索对应的接口 第二步,复制接口到apipost系统 第三步,复住到apipost系统 第四步骤,数据分析 第五步,生成python脚本,导入到python系统…

中年帕金森:守护健康,从容面对生活挑战

在快节奏的现代生活中,中年人群面临着越来越多的健康挑战。其中,帕金森病作为一种常见的神经系统疾病,逐渐引起了人们的关注。帕金森病不仅影响患者的身体健康,还对其日常生活造成极大的困扰。那么,我们该如何应对中年…

NLP自然语言处理课程设计—基于实体识别的智能任务系统

NLP课程设计-基于实体识别的智能任务系统 前言一、数据获取可行性分析和需求分析1. 数据获取可行性分析2. 需求分析 二、程序主要NLP技术2.1 文本分类技术2.2 中文命名实体识别2.2.1 BiLSTM(双向长短期记忆网络)2.2.2 CRF(条件随机场&#xf…

MT8766安卓4G核心板_MTK联发科PCBA方案开发

MT8766是联发科四核4G模块方案,安卓一体板。 采用台积电 12 nm FinFET 制程工艺,4*A53架构,Android 9.0操作系统,搭载2.0GHz 的 Arm NEON 引擎。提供了支持最新 OpenOS 及其要求苛刻的应用程序所需的处理能力,专为具有…

HTML5有哪些新特性?

目录 1.语义化标签:2.多媒体支持:3.增强型表单:4.绘图与图形:5.地理定位:6.离线应用与存储:7.性能与集成:8.语义化属性:9.改进的 DOM 操作:10.跨文档通信:11.…

电动汽车厂商Rivian将全新设计元素融入由虚幻引擎驱动的车机界面

Rivian Automotive(简称:“Rivian”),是美国一家电动汽车厂商,该品牌创办于2009年,总部位于加州埃尔文,专注于生产电动皮卡车Rivian R1T和电动SUV Rivian R1S。 Rivian的车主们正追寻这样一条道…

全氟己酮自动灭火材料表现亮眼!手把手教你自动灭火毯的使用方法

灭火毯的使用方法是什么?很多朋友在购买灭火毯之前,都比较关心这个问题。在这里,我们可以把灭火毯分为两种。一种是传统灭火毯,还有一种是近年来兴起的高科技产品—全氟己酮自动灭火毯。这两种灭火毯的使用方法大有不同&#xff0…

【Windows系统】文件操作出现“文件访问被拒绝”弹窗问题

环境 系统:win10x64 版本:1709 问题 重命名系统文件夹文件,有时会出现【文件访问被拒绝】的弹窗,导致操作失败。 如何才能避免弹窗,成功操作? 解决方法 前提:实施以下解决,首先…

30. 光纤耦合器

导论: 物理光学传播(POP)可用于计算光纤耦合效率。 设计流程: 光束建模和聚焦 在系统选项中选择系统孔径,在系统孔径下选择“入瞳直径”,并输入“4”。 设置0视场,选择角度。 加入1um波长。…

访问学者谈CSC青年骨干教师项目出国经历及感受

CSC青年骨干教师出国研修项目实施已近20年,越来越多的青年教师成为该项目的受益者。知识人网小编推荐该项目资助老师谈谈在加拿大卡尔加里大学访学一年的经历及感受。 国家留学基金委(以下简称CSC)高等学校青年骨干教师出国研修项目&#xff…

XUbuntu24.04之制作ISO镜像启动盘(二百四十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

iptables配置NAT实现端口转发

加载防火墙的内核模块 modprobe ip_tables modprobe ip_nat_ftp modprobe ip_conntrack 1.开启路由转发功能 echo net.ipv4.ip_forward 1 >> /etc/sysctl.conf sysctl -p2、将本地的端口转发到本机端口 将本机的 7777 端口转发到 6666 端口。 iptables -t nat -A PR…

Ubuntu-24.04-live-server-amd64安装界面中文版

系列文章目录 Ubuntu安装qemu-guest-agent Ubuntu-24.04-live-server-amd64启用ssh Ubuntu乌班图安装VIM文本编辑器工具 文章目录 系列文章目录前言一、准备工作二、开始安装三、测试效果总结 前言 Centos结束,转战Ubuntu。我之所以写这篇文章,是因为我…

Python基础教程——20个让人眼前一亮的逻辑妙用!

文末免费赠精品编程资料~~ Python不仅仅是一种编程语言,它还是解决问题的艺术,充满了让人拍案叫绝的“小巧思”。通过这15个小技巧,你不仅能提升编程技能,还能让你的代码更加优雅、高效。让我们一探究竟吧! 1. 列表推…

RAM和ROM

1,RAM和ROM区别 RAM和ROM都是由来存储的,比如CPU缓存,电脑和手机内存等属于RAM,而固态硬盘,U盘,手机的128G,256G存储空间等都属于ROM。他们的最主要区别是RAM在断电后存储数据就没有了,而ROM在断电后存储数…

采用了宽电压设计的测径仪为什么仍旧需要到现场勘察电力环境

关键字: 测径仪宽电压设计,测径仪电压范围,电压影响测径仪,测径仪车间电压 设备宽电压设计是指该设备能够在一定范围的电压波动内正常工作,而不会因为电压的轻微变化而导致性能下降或损坏。宽电压设计通常涉及到电源电路的优化和设计,以确保设备在电压波…