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 // 19p.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 的实例才可以触发拦截

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode 1355 活动参与者(postgresql)

需求 表: Friends ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | | activity | varchar | ---------------------- id 是朋友的 id 和该表的主键 name 是朋友的名字 activity 是朋友参加的活动的名字 表: Activit…

QT实现多摄像头监控

工具使用方法: 1、在add camera后面输入对应摄像头的IP后,点击add会自动布局显示。 2、在del camera后选择一个对应IP后,点击del会自动删除对应摄像头的显示,且整体布局会自动调整。 工具使用场景: 测试摄像头的好坏。…

探索CSS clip-path: polygon():塑造元素的无限可能

在CSS的世界里,clip-path 属性赋予了开发者前所未有的能力,让他们能够以非传统的方式裁剪页面元素,创造出独特的视觉效果。其中,polygon() 函数尤其强大,它允许你使用多边形来定义裁剪区域的形状,从而实现各…

Redis常见数据类型及其常用命令详解

文章目录 一、Redis概述二、Redis常用命令1.通用命令1.1 KEYS:查看符合模板的所有 key1.2 DEL:删除一个指定的 key1.3 EXISTS:判断 key 是否存在1.4 EXPIRE:给一个 key 设置有效期,有效期到期时该 key 会被自动删除1.5…

【读博日记】拓扑结构(待修正)

Topology 拓扑学 内容来源于互联网,还在甄别中——20240617 拓扑结构指把实体抽象成与其形状大小无关的点,把连接实体的线路抽象成线,再研究这些电线之间的关系。 所谓相似的拓扑结构: 例如一个圆环变成正方形、长方形、三角形…

.Net OpenCVSharp生成灰度图和二值图

文章目录 前言一、灰度图二、二值图 前言 使用OpenCVSharp生成图片的灰度图和二值图 .Net 8.0版本,依赖OpenCvSharp4和OpenCvSharp4.runtime.win组件。 原图: 提示:以下是本篇文章正文内容,下面案例可供参考 一、灰度图 /// &…

efficientsam-pytorch基于point、box和segment everthing推理模型

EfficientSAM 论文 EfficientSAM: Leveraged Masked Image Pretraining for Efficient Segment Anything https://arxiv.org/abs/2312.00863 模型结构 EfficientSAM模型利用掩码图像预训练(SAMI),该预训练学习从SAM图像编码器重构特征&a…

项目(一)--高并发内存池项目简介

什么是高并发内存池 它是一个全球性大厂google(谷歌)的 开源项目,项目名字叫tcmalloc,全称是Thread-Caching Malloc,即线程缓存的malloc 作用: 我们知道C语言在堆上开辟空间和 释放使用的是malloc和free函数 并且C的动态内存管理new和delete 的底层实际上也调用了…

【Linux】模拟实现一个简单的日志系统

👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…

SFNC —— 标准特征命名约定(一)

系列文章目录 SFNC —— 标准特征命名约定(一) 文章目录 系列文章目录1、介绍1.1 约定(Conventions)功能名称和接口(Feature Name and Interface)功能类别(Feature Category)功能级别…

(微服务实战)预付卡平台支付交易系统消费业务流程设计

1 交易系统技术架构 预付卡支付交易系统采用Dubbo3作为底层框架,支付交易系统分为账户系统、清结算系统、支付网关、核心支付系统等模块。系统整体采用微服务架构,容器化部署。 2 消费业务流程设计 预付卡系统消费场景分为线上和线下,线…

市场情绪周期2024-6-17(补涨回头潮视角验证)

竞价隔夜单 看长江通信,38亿涨到40亿又回落,那么周末最大的利好消息加持下,隔夜单不及预期,金溢科技 更是如此;空间板华闻集团8天7板,连扳5板,一字跌停,它也是有车联网的&#xff0c…

【UIDynamic-动力学-UICollisionBehavior-碰撞模式-创建边界 Objective-C语言】

一、我们来说这个碰撞模式 1.把之前的代码备份一下,改个名字:“04-碰撞行为-碰撞模式”, 然后,command + R,先跑一下, 我现在,一点击,是这个红色的View、和蓝色的View、在发生碰撞, 我们说,碰撞模式是啥意思, collision里边,有一个叫做collisionMode, UICollis…

c++里对 new 、delete 运算符的重载

(1)c 里 我们可以用默认的 new 和 delete 来分配对象和回收对象。 new 可以先申请内存,再调用对象的构造函数; delete 则先调用对象的析构函数,再回收内存。当然,当我们为类定义了 operator new () 和 oper…

双层循环和循环控制语句的使用,while和until的语法使用

双层循环和循环控制语句的使用,while和until的语法使用 exit echo 打印 -n 表示不换行输出 -e 输出转译字符 \b:相当于退格键(backspace) \n:换行,相当于回车 \f:换行,换行后的…

Git仓库中文件的状态

0 Preface/Foreword 1 文件状态 文件包含以下4个状态: untracked,未跟踪,表示该文件在文件夹中,但是没有加入到git 仓库中进行版本管控。可以通过git add命令将该文件增加到git 仓库中。从untracked变为staged。unmodified&…

HarmonyOS之自选股App

支持在 鸿蒙、安卓、苹果设备上运行。 1.界面效果展示 2.数据存储 数据存储采用的是官方的 ohos.data.relationalStore.relationalStore stock_code表用来存储A股市场5000多家公司的股票代码和名称等信息 const TAB_STOCK_CODE "stock_code" const CREATE_TABL…

为企业提供动力:用于大型组织的WordPress

可扩展且灵活的架构可通过主题、插件和集成进行定制内置 SEO 功能和营销功能内容管理和协作工具支持多站点安装托管解决方案和面向平台的提供商采用现代前端技术的 Headless CMS 功能 拥有强大、灵活且可扩展的内容管理系统 (CMS) 对于大型组织至关重要。作为最受欢迎和广泛使用…

双层循环和循环控制语句的使用,以及while和until的语法使用

echo 打印 -n 表示不换行输出 -e 输出转义字符 /b:相当于退格键(backspace) /n: 换行,相当于回车 /f: 换行,换行后的新行的开头连着上一行的行尾 /t: 相当于tab键 又叫做横向制…