编程语言
首页 > 编程语言> > JS关于数据代理_Object.defineProperty_Vue数据代理_双向绑定

JS关于数据代理_Object.defineProperty_Vue数据代理_双向绑定

作者:互联网

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

不可枚举性

通过 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

 

image-20221022000349813

问题所在

这俩好像有点关系,但好像又没有关系,就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

 

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. 上述案例就是个最基本的 数据代理

标签:jsp,数据库,代理
来源: