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

news2024/11/17 16:16:16

目录

属性描述符——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); // 输出: 42

obj.myProperty = 100; // 尝试修改属性值,但会失败
// "Attempt to set value to: 100" 这一行不会被打印
console.log(obj.myProperty); // 输出仍然是: 42


obj.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中如何添加渐变色带、多色色带

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

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

相关文章

Node之Web服务

前言 本文将讲解node的web服务 通过讲解http请求&#xff0c;node创建web服务等知识点让你更加深入的理解web服务和node创建的web服务 HTTP请求是什么&#xff1f; HTTP请求是客户端&#xff08;通常是浏览器或其他应用程序&#xff09;与服务器之间进行通信的一种方式。 …

onclick和@click有什么区别,究竟哪个更好使?

哈喽小伙伴们大家好,我是爱学英语的程序员,今天来给大家分享一些关于vue中事件绑定相关的内容,希望对大家有所帮助. 场景是这样的:我要实现一个切换栏,默认激活的是第一个标签,当鼠标移动到第二个标签是,对应的内容让激活.起初,我第一时间想到的是用element plus的组件来实现这…

从“NLP技术”到“AI大模型”

自从AI大模型问世以来&#xff0c;仿佛很少有人提及NLP技术这个词了。昨天休息的时候突然在想一个问题&#xff0c;AI大模型已经如此强大了&#xff0c;还需要传统的NLP技术吗&#xff1f; 传统的NLP技术指&#xff1a;从分词&#xff08;ws&#xff09;、词性标注&#xff08;…

【半导体行业推荐】PFA酸纯化器 特氟龙材质 酸蒸馏仪

PFA酸纯化器是一种实验室设备&#xff0c;专门用于制备高纯度的酸&#xff0c;这些高纯酸在化学分析、材料科学、半导体制造、光伏产业、生物医学研究等领域有着重要应用。以下是PFA酸纯化器的一些关键特性和功能&#xff1a; 1. 高效提纯&#xff1a;PFA酸纯化器通过先进的膜…

go语言day09 通道 协程的死锁

Go语言学习——channel的死锁其实没那么复杂 - JackieZheng - 博客园 (cnblogs.com) 目录 通道 创建通道 1&#xff09;无缓冲通道 2&#xff09;有缓冲通道 通道的使用 1) 值从通道入口进 2) 值从通道出口出 信道死锁&#xff1a; 0&#xff09;死锁现场0 1&#xff09;死…

Twitter批量发送消息api接口如何申请配置?

Twitter批量发送消息API接口的功能&#xff1f;接口有哪些限制&#xff1f; 企业和开发者越来越多地需要在Twitter上批量发送消息。然而&#xff0c;申请和配置这个接口需要一定的步骤和注意事项。AokSend将详细介绍如何申请和配置Twitter批量发送消息API接口。 Twitter批量发…

静力水准仪:测量与安装的全面指南

静力水准仪作为一种高精度的测量仪器&#xff0c;广泛应用于管廊、大坝、核电站、高层建筑、基坑、隧道、桥梁、地铁等工程领域&#xff0c;用于监测垂直位移和倾斜变化。本文将详细介绍静力水准仪的工作原理、特点及其安装过程中的注意事项&#xff0c;旨在为相关工程人员提供…

sql业务场景分析思路参考

1、时间可以进行排序&#xff0c;也可以用聚合函数对时间求最大值max&#xff08;时间&#xff09; 例如下面的例子&#xff1a;取最晚入职的人&#xff0c;那就是将入职时间倒序排序&#xff0c;然后limit 1 表&#xff1a; 场景&#xff1a;查找最晚入职员工的所有信息 se…

maven项目、idea抽风问题解决

开发的时候遇到奇奇怪怪的非技术问题&#xff0c;解决起来会费时间&#xff0c;做无用功。   这里记录常见的情况和解决方法 1.未识别maven项目 文件的图标变成了这种橙色的&#xff0c;而且有主启动函数也不能run 右键pom文件&#xff0c;点击Add as Maven Project 如果…

215. 数组中的第K个最大元素(中等)

215. 数组中的第K个最大元素 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转&#xff1a;215. 数组中的第K个最大元素 2.详细题解 快速排序算法在每一轮排序中&#xff0c;随机选择一个数字 x x x&#xff0c;根据与 x x x的大小关系将要排序的数…

C++ 引用——引用的基本语法

引用的基本使用 作用&#xff1a;给变量起别名 语法&#xff1a;数据类型 &别名 原名 示例&#xff1a; 运行结果&#xff1a;

【网络安全】漏洞挖掘之Spring Cloud注入漏洞

漏洞描述 Spring框架为现代基于java的企业应用程序(在任何类型的部署平台上)提供了一个全面的编程和配置模型。 Spring Cloud 中的 serveless框架 Spring Cloud Function 中的 RoutingFunction 类的 apply 方法将请求头中的“spring.cloud.function.routing-expression”参数…

【微信小程序开发实战项目】——花店微信小程序实战项目(4)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

创新引领,构筑产业新高地

在数字经济的浪潮中&#xff0c;成都树莓集团以创新驱动为核心&#xff0c;通过整合行业资源、优化服务、培养数字产业人才等措施&#xff0c;致力于打造产业高地&#xff0c;推动地方经济的高质量发展。 一、创新驱动&#xff0c;引领产业发展 1、引入新技术、新模式&#xf…

作为图形渲染API,OpenGL和Direct3D的全方位对比。

当你在网页看到很多美轮美奂的图形效果&#xff0c;3D交互效果&#xff0c;你知道是如何实现的吗&#xff1f;当然是借助图形渲染API了&#xff0c;说起这个不就不得说两大阵营&#xff0c;OpenGL和Direct3D&#xff0c;贝格前端工场在本文对二者做个详细对比。 一、什么是图形…

05-《猪笼草》

猪笼草 猪笼草是猪笼草属全体物种的总称。属于热带食虫植物&#xff0c;原产地主要为旧大陆热带地区。其拥有一个独特的吸取营养的器官——捕虫笼&#xff0c;捕虫笼呈圆筒形&#xff0c;下半部稍膨大&#xff0c;笼口上具有盖子&#xff0c;因其形状像猪笼而得名。 猪笼草 形…

【MySQL】事务实现原理

目录 事务 如何使用 ACID 原子性(Atomicity) 原子性实现原理 持久性(Durability) 持久性实现原理 隔离性 隔离级别 读未提交 读已提交 可重复读 串行化 隔离级别原理 锁 共享锁&独占锁 意向锁 索引记录锁 间隙锁 临键锁 插入意向锁 自增锁 MVCC 实现…

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

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

pdf压缩教程:pdf怎么压缩的小一点?6个方法轻松搞定!

大多数用户在上传PDF文件到网站时&#xff0c;常常遇到文件大小限制的问题。当PDF文件含有大量图片、图形和内容时&#xff0c;文件大小会变得过大&#xff0c;因此我们需要将其压缩至网站所要求的大小&#xff0c;才能成功上传。那么&#xff0c;pdf怎么压缩的小一点 呢&#…