vue实现数据双向绑定的原理:结合发布-订阅模式,通过ES5新增的Object.defineProperty()方法劫持各个属性的setter和getter,Observer监听数据的变动
Object.defineProperty(要修改的对象, 对象要修改的属性名称, 属性描述符)
属性描述符:数据描述符和存取描述符(存取描述符是由 getter 函数和 setter 函数所描述的属性)
数据描述符和存取描述符共享键值:
- configurable:属性是否能删改(是否可配),默认为false
- enumerable:属性是否出现在对象的枚举属性,默认为false
- writable:属性是否能被赋值运算符改变, 默认为false
数据描述符键值:
- value:属性对应的值,默认为undefined
- writable
存取描述符键值:
- set:属性的setter函数,默认为undefined
- get:属性的getter函数,默认为undefined
var o = {}; // 创建一个新对象
// 在对象中添加一个设置了数据描述符属性的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
// 给对象o添加一个a属性,值为37
// 在对象中添加一个设置了存取描述符属性的示例
var bValue = 38;
Object.defineProperty(o, "b", {
get() { return bValue; },
set(newValue) { bValue = newValue; },
enumerable : true,
configurable : true
});
o.b; // 38
// 给对象o添加一个b属性,值为 38
// 数据描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get() { return 0xdeadbeef; }
});
Object.defineProperties(要修改的对象, {对象属性名:{属性描述符},})
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
});