• 7_JS关于数据代理_Object.defineProperty_Vue数据代理_双向绑定


    回顾 object.defineProperty() 方法

    区别

    defineProperty == 给对象定义属性用的

    需要传递三个基本参数

    1. 需要定义属性的对象名
    2. 你要定义的属性叫什么名字(比如给person这个实体添加一个age属性)
    3. 配置项(对象类型的参数,里面存放键值对)

    image-20221021165746534

    <script>
        // 创建一个对象,该对象有两个基本属性
        var person = {
            name:"张三",
            sex:"男"
        }
        // 为person对象添加属性
        // 1、给那个对象添加?
        // 2、添加的属性名是什么?
        // 3、这个属性的基础配置项(对象类型,键值对形式)
        Object.defineProperty(person,"age",{
            value:18, // 该属性的值是
        })
    script>
    

    需求1

    • 对象person,添加一个属性age,有几种方式?
    • 三种
      1. 直接在 person对象当中添加属性;该属性值可以修改
        • image-20221021234035790
      2. 通过 .属性;对其设置;该属性值可以修改
        • image-20221021233941150
      3. 通过 Object.finedProperty()进行添加;该属性值不可枚举(不可修改) 默认情况下
        • image-20221021234126788

    不可枚举性

    通过 defineProperty添加的属性

    image-20221021234243445

    如果不设置配置项,那么该属性是不可枚举的;在控制台中可以看到,颜色变浅了

    image-20221021234337336

    该属性不参与遍历,我们可以测试下

    image-20221021234502785

    基本配置项

    value

    最开始配置的

    image-20221021234533851

    enumerable

    image-20221021234759192

    Object.defineProperty(person,"age",{
    value:18, // 该属性的值是
    enumerable:true, // 该配置项控制添加的属性是否参与枚举
    })
    

    writable

    设置属性是否可以被修改

    image-20221021235042150

    configurable

    控制属性是否可以被删除

    没有通过函数添加age属性的person对象

    image-20221021235630870

    通过函数添加age属性的person对象删除属性

    image-20221021235852707

    设置配置项删除掉age属性

    image-20221022000003394

    需求2

    • 准备一个变量 number,值为18
    • person当中有一个age属性,这个属性的value 是 number(不是手写的18)

    image-20221022000349813

    问题所在

    • 这个变量的值可能会发生改变,如果呢?
      • image-20221022000519427
    • 修改number,person对象当中的age值并没有发生改变
    • 同理,修改age,number也不会发生改变

    这俩好像有点关系,但好像又没有关系,就js代码加载的时候这俩自顶而下有了这一层关系,但也仅仅只有这一层

    image-20221022000643083

    那怎么完成这个需求呢?

    image-20221022000850459

    请看下方的高级配置项

    高级配置项

    get(getter)配置项

    image-20221022084643923

    解析

    1. 它的数据类型是一个对象
    2. 有人读取 person当中的age属性的时候get就会被调用
    3. 且get的返回值就是age 的 value
    4. 自定义get(getter函数)的时候,不能再使用基础配置了
      • image-20221022082704581

    那 返回一个 waves 字符串吧

    image-20221022082755645

    三个点儿

    1. invoke:映射
    2. property:属性
    3. getter:get配置项 == 函数
      • get是属性名
      • 他的类型是一个函数类型
      • 加在一起就是getter
        • image-20221022083532511

    image-20221022082826309

    • age 属性 是有的
    • 但是 value 是多少,目前不知道(...)
    • 想知道怎么办?点进去嘛

    image-20221022083735374

    get函数

    image-20221022084142173


    写个代码测试一下,打印一句话

    image-20221022084453981

    image-20221022084542759

    看样子是的,我前面的措辞有问题

    number与age进行关联

    image-20221022085613352

    对number值进行修改

    image-20221022085734444

    那么对age修改呢?

    image-20221022085858395

    问题所在

    1. 一定是 先访问age
    2. 再调用getter
    3. 当number的value发生改变的时候
    4. 再次访问age,那么就重新调用了getter函数
    5. 重新调用getter,会返回number,而这个number是修改过的,所以这边数据是同步了

    修改age;失败

    image-20221022090126038

    修改number,再访问age;成功

    image-20221022085734444

    set(setter)配置项

    同理,既然有get,那么与之相辅相成的就是set

    当你对age属性进行修改的时候,set(setter)函数就被调用

    且,调用的时候,会收到具体修改的 值

    /**
    * 需要传递一个参数value
    * 被调用的时候,会收到具体修改的值
    */
    set(value){
        // 当你对age属性进行修改的时候,set(setter)函数就被调用
        // 被调用的时候,会收到具体修改的值
        console.log("pseron.age属性发生修改,修改的值是",value);
    }
    

    测试

    image-20221022091237163

    实现双向绑定

    1. get函数
      • 实现了 number 与 age 的绑定,number发生修改的时候,age会发生变化
      • 当 age的值发生变化的时候,number值不变,所以无论怎么修改,age的值 === number
    2. set函数
      • 实现了 age 与 number 的绑定,age的值发生变化的时候,number的值也会跟着变化
      • set函数会接到 age所修改的value,将value 赋值 给 number,完成双向绑定

    image-20221022091606249

    测试

    image-20221022091937218

    总结

    通过案例

    1. number 与 person,是两个东西
    2. 但是借助 Object.defineProperty,使二者进行了关联
    3. person,确实是一个对象,age确实是person当中的属性
    4. 但是呢?你现用,我现去给你取
      • 靠谁取? == get
      • 靠谁改? == set

    什么是数据代理?

    定义

    通过一个对象,代理对另一个对象,中属性的操作 (读/写 == get/set)

    需求

    1. 我这里有两个对象,obj1 与 obj2;属性值如下
      • image-20221022103842562
    2. obj1 可以 对自身的 属性 x进行修改,访问
    3. 现在我想让 obj2 也有这个功能 == obj2 可以访问 obj1 的 x,并且也能对 x 进行修改

    实现

    这就需要借助我们的defineProperty

    image-20221022104222226

    <script>
        var obj1 = {
            x:100
        }
        var obj2 = {
            y:200
        }
        
        // 为 对象obj2 添加一个属性x,实现双向绑定
        Object.defineProperty(obj2,"x",{
            // 当访问obj2的x属性时
            get(){
                // 实际上是将 obj1的 x 属性返回
                return obj1.x;
            },
            // 当对 obj2的 x 属性进行修改的时候
            set(value){
                // 将收到的value值赋予给obj1的x属性即可
                obj1.x = value;
            }
        })
    script>
    

    测试

    1. obj1 与 obj2 身上是否都有x属性?
      • image-20221022104405623
    2. 修改 obj2的x属性,obj1的x属性是否会发生变化?
      • image-20221022104523116
    3. 上述案例就是个最基本的 数据代理
  • 相关阅读:
    如何在线进行图片压缩?
    tingpng 批量压缩工具
    Hadoop入门(二):手把手带你从零基础到完整安装配置
    前端不得不知道的知识-发布上线(vue为例)
    上周热点回顾(2.28-3.6)
    vue2 判断当前设备是移动端还是PC端
    2023东北电力大学计算机考研信息汇总
    计算机的基础知识
    ScrollView的OnValueChanged
    【linux】paramiko介绍 + 路由器设置tc命令使用
  • 原文地址:https://www.cnblogs.com/wavesbright/p/16815351.html