Vue学习笔记(三):Vue数据绑定原理

我们对一个Object对象设置属性时,一般是通过对象的.操作符或者[]操作符直接赋值的,例如obj1.a = 1 或 obj1[‘a’] = 1,通过这种方式添加的属性后续可以更改属性值,并且默认该属性是可枚举的,即通过for (const key in obj1) 或 obj1.keys()均可访问到属性。如果我们想在新增属性后不允许再更改属性值或者将该属性设置为非枚举属性,那我们该如何处理呢?

这个时候,我们就需要使用静态方法Object.defineProperty进行操作,Object.defineProperty方法可以通过对属性的元数据进行操作,控制属性行为。Object.defineProperty定义如下:

Object.defineProperty(obj, prop, descriptor)

参数

  • obj: Object,Required,要在其上定义属性的对象。
  • prop: String|Symbol,Required,要定义或修改的属性的名称。
  • descriptor: Object,Required,将被定义或修改的属性描述符。

返回值

Object,返回被传递给函数的对象obj。

Object.defineProperty(obj, prop, descriptor)中的参数descriptor就是属性描述符,就是定义属性行为的元数据信息。属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个Boolean类型的元数据属性,值为true或false,用于定义对属性的某种操作行为是允许还是禁止。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一,即descriptor要么是数据描述符,要么是存取描述符,不能同时包含数据描述符和存取描述符。

数据描述符和存取描述符均具有以下可选键值:

  • configurable: 当且仅当该属性的 configurable 为 true 时,才能够再次修改该属性的属性描述符,同时该属性也能从对应的对象上被删除。默认为 false。
  • enumerable: 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
  • value: 该属性的初始值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
  • writable: 当且仅当该属性的writable为true时,该属性才能被写入值。默认为 false。

例如,我们定义一个person对象,后续通过Object.defineProperty方法为person添加一个”age”属性,设置其初始值为18,并设置为可修改,代码如下:

<script type="text/javascript" >
    let person = {
        name:'张三',
        sex:'男',
    }

    Object.defineProperty(person,'age',{
        value:18,
        // enumerable:true, //控制属性是否可以枚举,默认值是false
        writable:true, //控制属性是否可以被修改,默认值是false
        // configurable:true //控制属性是否可以被删除,默认值是false
    })

    console.log(person)
script>

通过上述例子,我们可以看出,Object.defineProperty为对象属性增加了可操作性性。不过,这不是关键,关键是,Object.defineProperty中可以定义setter和gettter:

  • get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。
  • set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。

例如,我们定义一个变量num,并将其值赋值给person中新定义的属性age,最简单的做法就是定义person时,将num赋值给age:

<script type="text/javascript" >
    let num = 30
    let person = {
        name:'张三',
        sex:'男',
        age: num
    }
script>

但是,这么做只是让num在person定义时,将值赋给age,后续如果num值发生修改,age依然是最初的值,如果要让age值始终与num一致,通过Object.defineProperty可以这么做:

script>
    Object.defineProperty(person,'age',{
        // 读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
        get(){
            return num
        },
        // 修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
        set(value){
            num = value
        }
    })
script>

如下图片所示,在控制台无论num怎么修改,age属性值依然会跟着变化:

Vue学习笔记(三):Vue数据绑定原理

看到这,是不是有些明白了?有点Vue数据绑定的韵味了,是的,这就是Vue数据绑定的基础——数据绑定的原理。

Original: https://www.cnblogs.com/chenhuabin/p/15927183.html
Author: 奥辰
Title: Vue学习笔记(三):Vue数据绑定原理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/711651/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Maven实现多module打包成单个jar

    首先我们开发的项目一定会是一个父项目和多个子项目 1:我这里有多个子项目,多个项目都继承父项目2:start模块最终会依赖所有的模块,如果我们在打包前不对父项目进行先打包那么,我们…

    技术杂谈 2023年6月1日
    097
  • 减少仔猪的挤压死亡率的可穿戴设备简析

    在商业农场中,母猪压死小猪的情况经常发生。根据统计,大约每10头仔猪中就有1头被母猪挤压致死,在有机农场内,这种意外情况发生的频率更高。 根据爱荷华农业科技创业公司SwineTec…

    技术杂谈 2023年5月31日
    078
  • 预训练模型简要介绍

    从字面上看,预训练模型(pre-training model)是先通过一批语料进行训练模型,然后在这个初步训练好的模型基础上,再继续训练或者另作他用。这样的理解基本上是对的,预训练…

    技术杂谈 2023年7月11日
    084
  • 设计模式 19 备忘录模式

    备忘录模式(Memento Pattern)属于 行为型模式 2021 年 10 月 1 日下午,河南驻马店的一名 13 岁女中学生,因和同学发生不愉快喝下半瓶 百草枯。10 月 …

    技术杂谈 2023年7月25日
    061
  • Redis篇:事务和lua脚本的使用

    现在多数秒杀,抽奖,抢红包等大并发高流量的功能一般都是基于 redis 实现,然而在选择 redis 的时候,我们也要了解 redis 如何保证服务正确运行的原理 前言 redis…

    技术杂谈 2023年7月25日
    077
  • Linux 配置Git

    前言:请各大网友尊重本人原创知识分享,谨记本人博客: 南国以南i 一、用git –version命令检查是否已经安装 二、下载git源码并解压 wget https:/…

    技术杂谈 2023年7月11日
    081
  • Kubernetes: Kubesphere 和 Rancher

    Kubesphere 和 Rancher 如何做抉择? – 掘金https://juejin.cn/post/7030740701260316702 (40条消息) k…

    技术杂谈 2023年6月1日
    055
  • java学习之SpringMVC拦截器开发

    0x00前言 springmvc的拦截器类似于Selvet的Filter,但是所属的操作又不一样 Spring MVC 提供了 Interceptor 拦截器机制,用于请求的预处理…

    技术杂谈 2023年6月21日
    086
  • 联合省选 JSOI2022 游记

    Day 998244351 学了一下 NOI Linux 2.0 的使用,防止赛场上出现不知道如何操作的情况。 vscode 真好用! Day 998244352 尝试补了点模拟赛…

    技术杂谈 2023年6月21日
    079
  • Git 不识别文件名字母大小写变化

    问题 今天为一个项目撰写持续构建计划,撰写 Jenkinsfile 之后进行构建时报错: [2022-05-23 16:54:21] unable to prepare conte…

    技术杂谈 2023年7月11日
    063
  • Https是否加密URL参数和Header中的信息?(转载)

    HTTPS 会加密 header 和 body,而 URL 中 hostname 之后的部分是存在于 header 中的。 但注意 hostname 一般是会被明文传送的,因为 S…

    技术杂谈 2023年5月31日
    097
  • 通过tinc实现准sdwan

    原文: 通过Tinc实现内网穿透 简介 Tinc是一个开源的组网软件,相比之前的《通过ZeroTier实现内网穿透》,Tinc的配置较为繁琐(ZeroTier配置更简单,只需要注册…

    技术杂谈 2023年5月31日
    0116
  • Java: native

    解释 native主要用于 方法上 1、一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现…

    技术杂谈 2023年7月24日
    084
  • canvas绘制圆角头像

    如果你想绘制的网页包含一个圆弧形的头像的canvas图片,但是头像本身是正方形的,需要的方法如下:首先, 拿到头像在画布上的坐标和宽高:(具体怎么获取不在此做具体介绍)使用canv…

    技术杂谈 2023年5月31日
    0101
  • GO sync.Once

    高并发场景下,操作只执行一次,如读取配置、单例模式 Go 的sync模块提供了只执行一次的解决方案:sync.Once, 它只有一个函数:Do 执行: aa_1 Done 执行: …

    技术杂谈 2023年5月31日
    098
  • flask gevent

    flask的不同部署方式 使用gevent部署,只是在不同请求之间是异步的,同一个请求之间还是串行的。 https://iximiuz.com/en/posts/flask-gev…

    技术杂谈 2023年7月10日
    088
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球