defineProperty == 给对象定义属性用的
需要传递三个基本参数
- 需要定义属性的对象名
- 你要定义的属性叫什么名字(比如给person这个实体添加一个age属性)
- 配置项(对象类型的参数,里面存放键值对)
<script>
// 创建一个对象,该对象有两个基本属性
var person = {
name:"张三",
sex:"男"
}
// 为person对象添加属性
// 1、给那个对象添加?
// 2、添加的属性名是什么?
// 3、这个属性的基础配置项(对象类型,键值对形式)
Object.defineProperty(person,"age",{
value:18, // 该属性的值是
})
</script>
需求1
- 给 对象person,添加一个属性age,有几种方式?
- 三种
- 直接在 person对象当中添加属性;该属性值可以修改
- 通过 .属性;对其设置;该属性值可以修改
- 通过 Object.finedProperty()进行添加;该属性值不可枚举(不可修改) 默认情况下
- 直接在 person对象当中添加属性;该属性值可以修改
不可枚举性
通过 defineProperty添加的属性
如果不设置配置项,那么该属性是不可枚举的;在控制台中可以看到,颜色变浅了
该属性不参与遍历,我们可以测试下
基本配置项
value
最开始配置的
enumerable
Object.defineProperty(person,"age",{
value:18, // 该属性的值是
enumerable:true, // 该配置项控制添加的属性是否参与枚举
})
writable
设置属性是否可以被修改
configurable
控制属性是否可以被删除
没有通过函数添加age属性的person对象
通过函数添加age属性的person对象删除属性
设置配置项删除掉age属性
需求2
- 准备一个变量 number,值为18
- person当中有一个age属性,这个属性的value 是 number(不是手写的18)
问题所在
- 这个变量的值可能会发生改变,如果呢?
- 修改number,person对象当中的age值并没有发生改变
- 同理,修改age,number也不会发生改变
这俩好像有点关系,但好像又没有关系,就js代码加载的时候这俩自顶而下有了这一层关系,但也仅仅只有这一层
那怎么完成这个需求呢?
请看下方的高级配置项
高级配置项
get(getter)配置项
解析
- 它的数据类型是一个对象
- 当 有人读取 person当中的age属性的时候,get就会被调用
- 且get的返回值就是age 的 value值
- 自定义get(getter函数)的时候,不能再使用基础配置了
那 返回一个 waves 字符串吧
三个点儿
- invoke:映射
- property:属性
- getter:get配置项 == 函数
- get是属性名
- 他的类型是一个函数类型
- 加在一起就是getter
- age 属性 是有的
- 但是 value 是多少,目前不知道(…)
- 想知道怎么办?点进去嘛
get函数
写个代码测试一下,打印一句话
看样子是的,我前面的措辞有问题
number与age进行关联
对number值进行修改
那么对age修改呢?
问题所在
- 一定是 先访问age
- 再调用getter
- 当number的value发生改变的时候
- 再次访问age,那么就重新调用了getter函数
- 重新调用getter,会返回number,而这个number是修改过的,所以这边数据是同步了
修改age;失败
修改number,再访问age;成功
set(setter)配置项
同理,既然有get,那么与之相辅相成的就是set
当你对age属性进行修改的时候,set(setter)函数就被调用
且,调用的时候,会收到具体修改的 值
/**
* 需要传递一个参数value
* 被调用的时候,会收到具体修改的值
*/
set(value){
// 当你对age属性进行修改的时候,set(setter)函数就被调用
// 被调用的时候,会收到具体修改的值
console.log("pseron.age属性发生修改,修改的值是",value);
}
测试
实现双向绑定
- get函数
- 实现了 number 与 age 的绑定,number发生修改的时候,age会发生变化
- 当 age的值发生变化的时候,number值不变,所以无论怎么修改,age的值 === number
- set函数
- 实现了 age 与 number 的绑定,age的值发生变化的时候,number的值也会跟着变化
- set函数会接到 age所修改的value,将value 赋值 给 number,完成双向绑定
测试
总结
通过案例
- number 与 person,是两个东西
- 但是借助 Object.defineProperty,使二者进行了关联
- person,确实是一个对象,age确实是person当中的属性
- 但是值呢?你现用,我现去给你取
- 靠谁取? == get
- 靠谁改? == set
什么是数据代理?
定义
通过一个对象,代理对另一个对象,中属性的操作 (读/写 == get/set)
需求
- 我这里有两个对象,obj1 与 obj2;属性值如下
- obj1 可以 对自身的 属性 x进行修改,访问
- 现在我想让 obj2 也有这个功能 == obj2 可以访问 obj1 的 x,并且也能对 x 进行修改
实现
这就需要借助我们的defineProperty了
<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>
测试
- obj1 与 obj2 身上是否都有x属性?
- 修改 obj2的x属性,obj1的x属性是否会发生变化?
- 上述案例就是个最基本的 数据代理
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/291641.html