Object.defineProperty 和 Proxy 响应式原理 vue2 vue3

一、VUE2 响应式原理 Object.defineProperty 

Object.defineProperty 方法允许精确添加一个属性到对象上,或者修改对象的现有属性,并返回这个对象。它可以用来定义或修改属性的特性,如 value, writable, enumerable, 和 configurable

1) Object.defineProperty 这个方法接收三个参数:

1.属性所在的对象
2.属性的名字
3.一个描述符对象

描述对象:

1.configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为false。

2.enumerable:表示能否通过for in循环访问属性,默认值为false

3.writable:表示能否修改属性的值。默认值为false。

4.value:包含这个属性的数据值。默认值为undefined。

 // 理解属性var p1 = {name: "lisi",};Object.defineProperty(p1, "name", {configurable: false, // not deleteenumerable: false, // 能否通过for in循环访问属性,默认值为false});// delete删除属性console.log(p1); //{ name: 'lisi' }delete p1.name;console.log(p1); //{ name: 'lisi' }// 能否通过for in循环访问属性,默认值为falsefor (var i in p1) {console.log(p1[i]);} // lisi

2) 响应式原理实践:

var book = {_year: 2004,edition: 1,};Object.defineProperty(book, "year", {get: function () {return this._year;},set: function (newYear) {if (newYear > 2004) {this._year = newYear;this.edition += newYear - 2004;}},});book.year = 2005;console.log(book.edition); // 2console.log(book._year); //2005

参考别人写的demo:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><metaname="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>Document</title><style>#myInput {width: 400px;height: 50px;font-size: 40px;color: red;}#contain {margin-top: 20px;width: 400px;height: 200px;border: 1px solid salmon;}</style></head><body><input id="myInput" type="text" /><div id="contain"></div><script>var text;window.data = {};var oIn = document.getElementById("myInput");var oDiv = document.getElementById("contain");oIn.addEventListener("input", function (e) {text = e.target.value;console.log(text);window.data.value = text;});Object.defineProperty(window.data, "value", {get() {return "";},set(v) {oDiv.innerHTML = v;},});</script></body>
</html>

二、VUE3响应式原理 Proxy

Proxy 对象用于创建一个对象的代理,从而可以拦截和自定义对象的基本操作(如属性查找、赋值、枚举、函数调用等)。Proxy 提供了一种更灵活的方式来定义或修改对象的行为。

1)语法

// target : 需要封装的目标对象 // handler : 一些属性方法的集成(占位符对象) const proxy = new Proxy(target, handler);

常用的语法
拦截对属性的读取操作
get(target, property, receiver)

拦截对属性的写入操作
set(target, property, value, receiver)

拦截函数的调用
apply(target, thisArg, argumentsList)

判断对象是否拥有某个属性
has(target, property)

拦截删除属性的操作
deleteProperty(target, property)

2) 响应式原理代码

 const handler = {// 拦截目标对象的属性读取操作get(target, prop, receiver) {console.log(`访问了${prop}属性`);// 使用Reflect.get执行目标对象的属性读取操作return Reflect.get(target, prop, receiver);},// 拦截目标对象的属性设置操作set(target, prop, value, receiver) {console.log(`设置了${prop}属性`);// 使用Reflect.set执行目标对象的属性设置操作return Reflect.set(target, prop, value, receiver);},};// 创建一个目标对象const target = {name: "Alice",age: 20,};// 创建一个代理对象const proxy = new Proxy(target, handler);// 使用代理对象执行各种操作console.log(proxy.name); // 访问了name属性,输出Aliceproxy.age = 21; // 设置了age属性console.log(proxy.age); // 访问了age属性,输出21

三、object.definePropery 和 Proxy的区别
1) Object.defineProperty()语法
重点:vue为什么对数组对象的深层监听无法实现,因为组件每次渲染都是将data里的数据通过defineProperty进行响应式或者双向绑定上,之前没有后加的属性是不会被绑定上,也就不会触发更新渲。

Object.defineProperty( Obj, 'name', {enumerable: true, //可枚举configurable: true, //可配置// writable:true, //跟可配置不能同时存在// value:'name',  //可写死直get: function () {return def},set: function ( val ) {def = val}
} )


 2) Proxy的语法
 

//两个参数,对象,13个配置项
const handler = {get: function(obj, prop) {return prop in obj ? obj[prop] : 37;},set:function(){ },...13个配置项
};
const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b);      // 1, undefined
console.log('c' in p, p.c); // false, 37


对比了上面两种语法是不是就懂了,defineProperty只能响应首次渲染时候的属性,Proxy需要的是整体,不需要关心里面有什么属性,而且Proxy的配置项有13种,可以做更细致的事情,这是之前的defineProperty无法达到的

对比

  • 灵活性Proxy 提供了更多的灵活性和强大的拦截能力,可以拦截几乎所有的 JavaScript 操作。
  • 兼容性Object.defineProperty 有更广泛的浏览器兼容性,而 Proxy 可能不被所有旧浏览器支持。
  • 性能:在某些情况下,使用 Object.defineProperty 可能比 Proxy 更快,因为 Proxy 需要更多的设置和拦截。
  • 易用性Object.defineProperty 相对简单,易于理解和使用,而 Proxy 则提供了更复杂的功能,但学习曲线更陡峭。


 

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

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

相关文章

YOLOv8+PyQt5苹果叶病害检测(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测)

效果视频&#xff1a;YOLOv8PyQt5苹果叶病害检测系统完整资源集合 资源包含可视化的苹果叶病害检测系统&#xff0c;基于最新的YOLOv8训练的苹果叶病害检测模型&#xff0c;和基于PyQt5制作的可视苹果叶病害系统&#xff0c;包含登陆页面和检测页面&#xff0c;该系统可自动检…

操作符:->

在一个指针变量指向一个结构体时常常会用->操作符来使用结构体内部的成员&#xff0c; 下面是我们没有使用指针时&#xff0c;如何调用结构体内的成员&#xff0c; #include<stdio.h>struct stu {char name[20];int age;char number[20]; };int main() {struct stu …

python实现——分类类型数据挖掘任务(图形识别分类任务)

分类类型数据挖掘任务 基于卷积神经网络&#xff08;CNN&#xff09;的岩石图像分类。有一岩石图片数据集&#xff0c;共300张岩石图片&#xff0c;图片尺寸224x224。岩石种类有砾岩&#xff08;Conglomerate&#xff09;、安山岩&#xff08;Andesite&#xff09;、花岗岩&am…

学会这14大招,30天涨粉两三千没问题!沈阳新媒体运营培训

很多小白在刚转入公司做新媒体时&#xff0c;基本都是从帮助公司运营账号开始的。但不同于个人号&#xff0c;一个企业本身是没有ip属性的&#xff0c;它的风格、调性等&#xff0c;都需要通过你的运营&#xff0c;让它变成一个活灵活现的、赋予独立个性人设的账号。 目前&…

Isaac Lab支持的强化学习框架介绍

在Isaac Lab中使用rl_games强化学习框架进行机械臂训练实验 python source/standalone/workflows/rl_games/train.py --taskIsaac-Franka-Cabinet-Direct-v0 使用 RL 代理进行培训 — Isaac Lab 文档 --- Training with an RL Agent — Isaac Lab documentation (isaac-sim.g…

能匠教育影视后期学员江颢:机电工程系的男大学生的意外收获!

江颢,一个热爱学习的大三学生。他是机电工程系的学生,因为女朋友喜欢拍照,经常让他剪辑视频,刚开始也只是用剪映马马虎虎剪辑,技术有限,总是剪不出想要的感觉和意境,女朋友也觉得不太满意。所以想提升下剪辑能力,后面,偶然发现能匠教育这个影视后期学习和接单信息。他一开始只是…

【Vue】指令修饰符

文章目录 一、按键修饰符二、v-model修饰符三、事件修饰符 指令修饰符&#xff1a;就是通过 “.” 指明一些指令后缀&#xff0c;不同的后缀封装了不同的处理操作 —> 简化代码 一、按键修饰符 按键修饰符 keyup.enter —>当点击enter键的时候才触发 v-model修饰符 v-m…

重学java 60.IO流 字节流 ① File类

明年此日青云去&#xff0c;却笑人间举子忙 —— 24.6.4 知识回顾 1 .HashMap a.特点:无序,无索引,key唯一,线程不安全,可以存null键null值 b.数据结构:哈希表 c.方法:put remove get keyset entryset values containsKey 2.LinkedHashMap : a.特点:有…

Mybatis不明白?就这一篇带你轻松入门

引言&#xff1a;烧脑的我一直在烧脑的寻找资料&#xff0c;寻找网课&#xff0c;历经磨难让一个在大一期间只会算法的我逐渐走入Java前后端开发&#xff0c;也是一直在自学的道路上磕磕碰碰&#xff0c;也希望这篇文章对于也是同处于自学的你有所帮助&#xff0c;也希望你继续…

三生随记——鬼影膏药

深秋的夜晚&#xff0c;寒风凛冽&#xff0c;月光苍白如纸&#xff0c;洒在寂静无声的小镇上。这个镇子名叫“影落镇”&#xff0c;镇上流传着一个关于神秘膏药的恐怖传说。 传说在百年前&#xff0c;镇上有一位名叫林鬼影的医师&#xff0c;他医术高超&#xff0c;却性格古怪&…

备考系统架构设计师,看这篇就够了!(包括核心总结、真题、论文、模拟试题索引)

注&#xff1a;以下章节核心总结来自最新版课本&#xff1a;系统架构设计师教程&#xff08;第2版&#xff09;: https://url35.ctfile.com/f/52515535-1268514286-ca9b3a?p6235 ( 访问密码: 6235, 电子版 pdf 文件大小: 168.9 M &#xff0c;需要的话可自行下载&#xff0c;…

开源模型应用落地-LangChain试炼-LCEL-表达式语言(一)

一、前言 尽管现在的大语言模型已经非常强大&#xff0c;可以解决许多问题&#xff0c;但在处理复杂情况时&#xff0c;仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而&#xff0c;现在可以利用langchain来使得模型的应用变得更加直接和简单。 LCEL是什么&…

最强总结!18个机器学习核心算法模型!!

前言 大家好~在学习机器学习之后&#xff0c;你认为最重要的算法模型有哪些&#xff1f;今儿的内容涉及到 线性回归逻辑回归决策树支持向量机朴素贝叶斯K近邻算法聚类算法神经网络集成方法降维算法 我把每种算法模型的核心公式和代码也列举了出来&#xff0c;如果有其他比较重…

喜讯丨泰迪智能科技实力中标“健康大数据与人工智能实验室建设”项目

泰迪智能科技以健康数据分析与应用为主题的实验中心&#xff0c;为学校大健康产业大数据与人工智能应用人才培养提供载体&#xff0c;并基于培养中心根据学生专业的不同&#xff0c;提供不同的健康大数据学习资源&#xff0c;实现健康大数据技术和数据分析应用能力培养普遍提升…

四川九旋电子商务有限公司引领行业创新风潮

在数字化浪潮席卷而来的今天&#xff0c;电商行业正经历着前所未有的变革。四川九旋电子商务有限公司&#xff0c;作为抖音电商领域的佼佼者&#xff0c;凭借其前瞻性的战略眼光和强大的执行能力&#xff0c;在竞争激烈的市场中脱颖而出&#xff0c;成为行业的领跑者。 九旋电…

CUDA12.0 + cuDNN9.0.0安装

目录 1. 查看显卡支持的CUDA版本1.1 指令查看1.2 控制面板查看 2. 安装CUDA2.1 下载2.2 安装2.3 验证 3. 安装cuDNN3.1 下载3.2 安装3.2 验证 1. 查看显卡支持的CUDA版本 1.1 指令查看 打开cmd输入nvidia-smiDriver Version表示显卡驱动版本&#xff0c;CUDA Version表示支持…

AC自动机(查询)

上面讲了AC自动机是如何建树和建自动机的&#xff0c;这里要讲的是AC自动机的查询和各个数组的功能和作用。 其实AC自动机的查询和KMP算法是及其相近的&#xff0c;都是一个指针跑主串&#xff0c;另一个指针跑ne串&#xff08;这里就是回跳边&#xff09;。 话都说到这了&…

行车记录仪人体感应雷达开关模块,飞睿智能雷达模块穿透玻璃、告别漏触烦恼,安防停车监控新方案

随着汽车保有量的持续增长&#xff0c;行车记录仪作为汽车安全配件的必备品&#xff0c;其重要性日益凸显。然而&#xff0c;传统的行车记录仪传感器在停车时往往存在无法穿透玻璃、漏触等问题&#xff0c;给车主带来了诸多不便和安全隐患。本文将深入探讨停车场景下&#xff0…

博客目录~

1、Jenkins构建打包部署前端Vue项目至Nginx-CSDN博客 2、https://blog.csdn.net/askuld/article/details/139429298 3、基于DockerJenkins实现自动部署SpringBootMaven项目-CSDN博客 4、时序数据库ClickHouse的安装使用_clickhouse安装使用-CSDN博客 5、Valid&#xff0c…

github用存在的私钥在Linux上配置免密登录

github用存在的私钥在Linux上配置免密登录 如题&#xff0c;githu的密钥需要再其他机器(linux)上使用&#xff0c;当然重新生成按照官网的步骤配置即可。 但是&#xff0c;我已经配置过密钥对&#xff0c;私钥我本地也有&#xff08;windows&#xff09;&#xff0c;那么&#…