当前位置: 首页 > news >正文

属性描述符初探——Vue实现数据劫持的基础

目录

属性描述符——Vue实现数据劫持的基础

一、属性描述符是什么?

​编辑

1.1、属性描述符示例

1.2、用属性描述符定义属性及获取对象的属性描述符

1.3、带有读取器和设置器的属性描述符

二、使用属性描述符的情景

2.1、封装和数据隐藏

        使用getter和setter来封装一个对象的内部状态,防止直接访问和修改。

2.2、 创建只读属性

        通过设置writable为false,可以创建一个不允许修改的属性。

 2.3、验证属性赋值

        在setter中添加逻辑来验证属性值,确保它们满足特定条件。

三、情景:如果属性描述符中writable为false,但是写了set函数

四、总结与相关资源


        请注意,本文讲述的是JS中的属性描述符,不是Python中的属性描述符

属性描述符——Vue实现数据劫持的基础

一、属性描述符是什么?

        属性描述符(Property Descriptor)在JavaScript中是一个特殊的对象,它定义了对象属性的行为和特性。

        属性描述符是一个对象,它通常包含以下几个属性:

  • value:属性的值。这是一个数据属性的特性,用于存储属性值。
  • writable:一个布尔值,表示属性的值是否可被修改。如果设置为false,属性值将不可修改。
  • get:一个函数,当访问属性时调用,用于获取属性值。这是一个访问器属性的特性。
  • set:一个函数,当设置属性值时调用,用于设置属性值。这是一个访问器属性的特性。
  • enumerable:一个布尔值,表示属性是否可被枚举,默认为false。如果设置为true,则属性会显示在for-in循环和Object.keys()的结果中。
  • configurable:一个布尔值,表示属性的属性描述符是否可以被改变,以及属性是否可以被删除。如果设置为false,属性将不能被删除,且其属性描述符不能被改变。

         属性描述符的属性树如下:

1.1、属性描述符示例

        属性描述符示例如下:

let descriptor = {value: 42,writable: true,enumerable: true,configurable: true
};

        在这个例子中,descriptor是一个属性描述符对象,它定义了一个数据属性,该属性具有可写的值、可枚举和可配置的特性。

1.2、用属性描述符定义属性及获取对象的属性描述符

        要使用属性描述符来定义或修改对象属性,可以使用Object.defineProperty()方法,此外,还可以使用Object.getOwnPropertyDescriptor()来获取对象属性的当前属性描述符

let obj = {};Object.defineProperty(obj, 'myProp', {value: 42,writable: true,enumerable: true,configurable: true
});// 获取对象属性的当前属性描述符let propDesc = Object.getOwnPropertyDescriptor(obj, 'myProp');console.log(propDesc);// 输出:{ value: 42, writable: true, enumerable: true, configurable: true }

1.3、带有读取器和设置器的属性描述符

        带有读取器(getter)和设置器(setter)的属性描述符允许你定义属性的获取和设置行为,而不是直接存储一个值。这种属性被称为访问器属性。以下是一个带有读取器和设置器的属性描述符的例子:

let obj = {};// 定义属性描述符,包含读取器和设置器
let descriptor = {get: function() {// 这个函数会在访问属性时被调用console.log('Getting the value!');return this._myValue; // 访问器返回内部属性的值},set: function(newValue) {// 这个函数会在设置属性值时被调用console.log('Setting the value to ' + newValue);this._myValue = newValue; // 设置器将值存储到内部属性},enumerable: true, // 属性是否可枚举configurable: true  // 属性的描述符是否可以被改变
};// 使用属性描述符定义属性
Object.defineProperty(obj, 'myProperty', descriptor);// 测试读取器
console.log(obj.myProperty); // 输出: 'Getting the value!' 然后是 undefined// 测试设置器
obj.myProperty = 10; // 输出: 'Setting the value to 10'
console.log(obj.myProperty); // 输出: 'Getting the value!' 然后是 10

        其中,对obj中myProperty属性进行赋值,就会触发设置器,读取obj的myProperty属性,就会触发读取器。

二、使用属性描述符的情景

2.1、封装和数据隐藏

        使用getter和setter来封装一个对象的内部状态,防止直接访问和修改。
// 使用getter和setter来封装一个对象的内部状态,防止直接访问和修改。let user = {_name: 'Alice',get name() {return this._name;},set name(value) {if (typeof value === 'string') {this._name = value;} else {console.log('Name must be a string.');}}
};console.log(user.name); // Alice
user.name = 'Bob'; // 更新名称
console.log(user.name); // Bob
user.name = 123; // 尝试设置非法名称,将显示错误信息

2.2、 创建只读属性

        通过设置writable为false,可以创建一个不允许修改的属性。
// 通过设置writable为false,可以创建一个不允许修改的属性。let product = {_price: 19.99,get price() {return this._price;}
};Object.defineProperty(product, 'price', {writable: false,enumerable: true,configurable: true
});console.log(product.price); // 19.99
// product.price = 24.99; // 这将不会改变价格,因为属性是只读的

 2.3、验证属性赋值

        在setter中添加逻辑来验证属性值,确保它们满足特定条件。
// 在setter中添加逻辑来验证属性值,确保它们满足特定条件。let account = {_balance: 0,get balance() {return this._balance;},set balance(amount) {if (amount < 0) {console.log('Cannot set a negative balance.');} else {this._balance = amount;}}
};account.balance = 1000; // 设置余额
console.log(account.balance); // 1000
account.balance = -500; // 尝试设置负余额,将显示错误信息

三、情景:如果属性描述符中writable为false,但是写了set函数

        如果属性描述符中的 writable 属性设置为 false,这意味着属性的值不能被重新赋值。此时如果尝试通过 set 函数修改属性值,它将不会对属性的实际值产生任何影响,因为 writable 属性已经明确禁止了对值的修改。

let obj = {};let descriptor = {value: 42,writable: false, // 禁止修改属性值set: function(newValue) {console.log(`Attempt to set value to: ${newValue}`);// 尽管这里尝试设置新值,但由于 writable: false,这个操作不会有任何效果// 甚至连`Attempt to set value to: ${newValue}`都不会打印// writable: false情况下,不会触发设置器函数},enumerable: true,configurable: true
};Object.defineProperty(obj, 'myProperty', descriptor);console.log(obj.myProperty); // 输出: 42obj.myProperty = 100; // 尝试修改属性值,但会失败
// "Attempt to set value to: 100" 这一行不会被打印
console.log(obj.myProperty); // 输出仍然是: 42obj.myProperty = 'new value'; // 再次尝试修改属性值,但仍然会失败
console.log(obj.myProperty); // 输出仍然是: 42

四、总结与相关资源

        属性描述符还有很多内容可以挖掘,比如defineProperty与Proxy的区别,比如vue2与vue3实现数据劫持的方式有什么不同,实现效果有哪些差异等,这篇博文只是入门,以后有时间再深挖。

        博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

        更多优质内容,请关注:

JS底层逻辑:

        最细最有条理解析:事件循环(消息循环)是什么?进程与线程的定义、关系与差异

        路由通配符,小小的字符有大大的作用,你真的熟悉吗? 

        管理数据必备!侦听器watch用法详解

        什么是深拷贝?深拷贝和浅拷贝有什么区别

JS语法篇:

        你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解

        对象数据的读取,看这一篇就够了!

        通过array.every()实现数据验证、权限检查和一致性检查,array.some与array.every的区别

        通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理

        通过array.map()实现数据转换、创建派生数组、异步数据流处理、搜索和过滤等需求

        通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式等

        通过array.filter()实现数组的数据筛选、数据清洗和链式调用

巧妙算法与窍门:

        多维数组操作,不要再用遍历循环foreach了,来试试数组展平的小妙招!

        别再用双层遍历循环来做新旧数组对比,寻找新增元素了!

        shpfile转GeoJSON且控制转化精度;如何获取GeoJSON?GeoJson结构详解

        Mapbox添加行政区矢量图层、分级设色图层、自定义鼠标悬浮框、添加天地图底图等

Element plus拓展:

        通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称等

        el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能

        el-table中如何添加渐变色带、多色色带

相关文章:

属性描述符初探——Vue实现数据劫持的基础

目录 属性描述符——Vue实现数据劫持的基础 一、属性描述符是什么&#xff1f; ​编辑 1.1、属性描述符示例 1.2、用属性描述符定义属性及获取对象的属性描述符 1.3、带有读取器和设置器的属性描述符 二、使用属性描述符的情景 2.1、封装和数据隐藏 使用getter和setter…...

字节也没余粮了?天底下没有永远免费的GPT-4;AI产品用订阅制就不合理!让用户掏钱的N种定价技巧嘿嘿 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;ShowMeAI官网 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 1. 当 Coze 也开始收费&#xff1a;天底下没有「永远」免费的 GPT-4 注&#xff1a;这里 Coze 指海外版。国内版 扣子 还是免费。 Coze (海外版) 官网链接 → htt…...

【Matlab 路径优化】基于蚁群算法的XX市旅游景点线路优化系统

基于蚁群算法的XX市旅游景点线路优化系统 &#xff08;一&#xff09;客户需求&#xff1a; ①考虑旅游景点的空间分布、游客偏好等因素&#xff0c;实现了旅游线路的智能规划 ②游客选择一景点出发经过所要游览的所有景点只一次&#xff0c;最后回到出发点的前提下&#xf…...

我关于Excel使用点滴的笔记

本篇笔记是我关于Excel使用点滴的学习笔记&#xff0c;摘要和地址链接列表。临时暂挂&#xff0c;后面可能在不需要时删除。 (笔记模板由python脚本于2024年06月28日 12:23:32创建&#xff0c;本篇笔记适合初通Python&#xff0c;熟悉六大基本数据(str字符串、int整型、float浮…...

【Java安装】windows10+JDK21+IDEA

文章目录 一、JDK安装1. 下载完成后按照自己需要的位置安装2. 配置环境变量2.1 JAVA_HOME变量2.2 PATH配置 3. 验证4. helloworld 二、IDEA安装三、IDEA-HelloWorld 一、JDK安装 JDK安装链接 1. 下载完成后按照自己需要的位置安装 2. 配置环境变量 2.1 JAVA_HOME变量 安装…...

《简历宝典》01 - 一文带你学会如何写一份糟糕透顶的简历

我们每个人几乎都会面对找工作这件事&#xff0c;而找工作或者说求职首先就是要写一份简历。今天狗哥将以一个不同的视角带你写一份无与伦比&#xff0c;糟糕透顶的求职简历&#xff0c;说实话&#xff0c;其实几年前&#xff0c;我就是这么写的。 目录 1. 文件名 2. 基本信…...

多链路聚合通信路由在应急救援活动中的重要性及解决方案

在应急救援指挥活动中&#xff0c;多链路聚合通信设备如同一座坚固的桥梁&#xff0c;将信息快速、准确地传递至每一个角落。面对复杂多变的救援现场&#xff0c;这类设备展现了其卓越的适应性和稳定性。 想象一下&#xff0c;当灾害突然降临&#xff0c;信息的传递变得至关重…...

PyCharm中如何将某个文件设置为默认运行文件

之前在使用JetBrain公司的另一款软件IDEA的时候&#xff0c;如果在选中static main函数后按键altenter可以默认以后运行Main类的main函数。最近在使用PyCharm学习Python&#xff0c;既然同为一家公司的产品而且二者的风格如此之像&#xff0c;所以我怀疑PyCharm中肯定也有类似的…...

【杂交版】植物大战僵尸杂交版v2.1最新版本下载链接

B站游戏作者潜艇伟伟迷于6月13日中午更新了植物大战僵尸杂交版2.1版本&#xff0c;有老版本的也可以完美继承存档数据。 不多废话下载链接放上&#xff1a; 夸克网盘链接&#xff1a;https://pan.quark.cn/s/095de551d1d1 UC网盘链接&#xff1a;https://drive.uc.cn/s/86debb3…...

图像增强及运算篇之图像掩膜直方图和HS直方图

一.图像掩膜直方图 如果要统计图像的某一部分直方图&#xff0c;就需要使用掩码&#xff08;蒙板&#xff09;来进行计算。假设将要统计的部分设置为白色&#xff0c;其余部分设置为黑色&#xff0c;然后使用该掩膜进行直方图绘制&#xff0c;其完整代码如下所示。 # -*- codi…...

Python商务数据分析知识专栏(六)——Python数据分析的应用④Python数据分析实训

Python商务数据分析知识专栏&#xff08;六&#xff09;——Python数据分析的应用④Python数据分析实训 Python数据分析实训一.iris数据处理实训1.1 拓展学习资料&Python环境介绍1.2 读取数据&修改列名称1.3 以PythonConsole方式执行代码1.4 缺失值处理1.5 重置索引 二…...

【Python机器学习】处理文本数据——将文本数据表示为词袋

用于机器学习的文本有一种最简单的方法&#xff0c;也是最有效且最常用的方法&#xff0c;就是使用词袋表示。使用这种表示方法时&#xff0c;我们舍弃了输入文本中的大部分结构&#xff0c;比如章节、段落、句子和格式&#xff0c;只计算语料库中&#xff0c;只计算语料库中每…...

论文写作全攻略:Kimi辅助下的高效学术写作技巧

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 完成论文写作是一个多阶段的过程&#xff0c;涉及到不同的任务和技能。以下是按不同分类总结的向Kimi提问的prompt&#xff0c;以帮助你在论文写作过程中取得成功&#xff1a; 1. 选题与…...

通证经济重塑经济格局

在数字化转型的全球浪潮中&#xff0c;通证经济模式犹如一股新兴力量&#xff0c;以其独特的价值传递与共享机制&#xff0c;重塑着经济格局&#xff0c;引领我们步入数字经济的新纪元。 通证&#xff0c;作为这一模式的核心&#xff0c;不仅是权利与权益的数字化凭证&#xf…...

linux - cp 命令

问&#xff1a;cp -r ./src/. ./dst 与 cp -r ./src/* ./dst 有什么区别? 1.隐藏文件和目录&#xff1a;cp -r ./src/* ./dst 不会复制隐藏文件和目录。cp -r ./src/. ./dst 会复制所有文件和目录&#xff0c;包括隐藏文件和目录。 2.通配符和当前目录&#xff1a;* 是一个通…...

基于Qt实现的PDF阅读、编辑工具

记录一下实现pdf工具功能 语言&#xff1a;c、qt IDE&#xff1a;vs2017 环境&#xff1a;win10 一、功能演示&#xff1a; 二、功能介绍&#xff1a; 1.基于saribbon主体界面框架&#xff0c;该框架主要是为了实现类似word导航项 2.加载PDF放大缩小以及预览功能 3.pdf页面跳转…...

Linux 内核 GPIO 用户空间接口

文章目录 Linux 内核 GPIO 接口旧版本方式&#xff1a;sysfs 接口新版本方式&#xff1a;chardev 接口 gpiod 库及其命令行gpiod 库的命令行gpiod 库函数的应用 GPIO&#xff08;General Purpose Input/Output&#xff0c;通用输入/输出接口&#xff09;&#xff0c;是微控制器…...

Hive数据倾斜--处理方法

1. 什么是数据倾斜&#xff1f; 在分布式计算场景下&#xff0c;大量的数据集中在某一个节点而导致一个任务的执行时间变长。而大量的节点只处理了小部分的数据&#xff0c;大数据组件处理海量数据的特点就是不患多&#xff0c;而患不均。 2. 怎么发现任务出现了数据倾斜现象 …...

k8s流控平台apiserver详解

一、简单理解认识apiserver 1.主要功能 认证 鉴权 准入 mutating validating admission 限流 2.概念 apiserver保护etcd&#xff0c;缓存机制&#xff0c;有缓存直接返回&#xff0c;没缓存再去查看etcd,apiserver是担任和其他平台同信并认证 3.访问控制概览…...

unity对于文件夹的操作

1、获取目标文件夹内所有文件夹 string[] directories Directory.GetDirectories(Path);for (int i 0; i < directories.Length; i){print(directories[i]);}2、获取目标文件夹内指定文件 public List<string> GetAllTxt(string path){//只获取文件名string[] files…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.

这个警告表明您在使用Vue的esm-bundler构建版本时&#xff0c;未明确定义编译时特性标志。以下是详细解释和解决方案&#xff1a; ‌问题原因‌&#xff1a; 该标志是Vue 3.4引入的编译时特性标志&#xff0c;用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...