一、区分响应式、双向绑定
- 响应式:数据改变驱动视图的改变,是单向的
- 双向绑定:试图反过来改变数据,双向的, 也就是说响应式是双向绑定的一环,
二、 Object.defineProperty()语法说明
Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineProperty(obj, prop, desc)
- obj 需要定义属性的当前对象
- prop 当前需要定义的属性名
- desc 属性描述符
三、属性描述符
1. 数据描述符 --特有的两个属性(value、writable、enumerable)
Object.defineProperty(obj, 'a', {
value: 3,
// 是否可写
writable: true,
// 是否可以被枚举
enumerable: true
})
属性说明 | 属性 | 默认值 | 可选值 |
响应式对象的属性值 | value | -- | -- |
属性的值是否可写(是否可以改变value的值) | writable | false | true(可写) || false(只读) |
属性是否可以被枚举 | enumerable | false | true(可被枚举) || false(不可被枚举) |
2、存取器描述(getter、setter)
注意:当使用了getter或setter方法,不允许使用writable和value这两个属性
get: 一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回的值被用作属性值。默认为undefined
set: 一个给属性提供serter的方法,如果没有serter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined
(1)、基础使用
var obj = {};
var initValue = "hello";
Object.defineProperty(obj, "key", {
get() {
return initValue; //当获取值的时候触发的函数
},
set(value) {
initValue = value; //当设置值的时候触发的函数,设置的新值通过参数value拿到
},
});
//获取值
console.log(obj.key); //hello
//设置值
obj.key = "change value";
console.log(obj.key); //change value
注意:get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined
(2)、封装存取器的封装
单个封装
var obj = {}
function defineReactive(data, key, val) {
// console.log("val", val)
Object.defineProperty(data, key, {
// 可枚举
enumerable: true,
// 可以被配置,比如可被delete
configurable: true,
// 上面两个配不配置都无所谓 一般都加上
get() {
return val
},
set(newValue) {
if(val === newValue) {
return;
}
val = newValue
}
})
}
defineReactive(obj, 'a', 10)
console.log(obj.a)
obj.a = 900
console.log(obj.a)