其原理:在Vue中其实就是通过Object.defineProperty来劫持对象属性的setter和getter操作,并“种下”一个监听器,当数据发生变化的时候发出通知。
那我们先来了解一下Object.defineProperty:
语法
Object.defineProperty(obj,target,texing)参数说明:
obj:-操作的对象
target:需定义或修改的属性的名字
texing:目标属性所拥有的特性可供定义的特性列表
value:属性的值
writable:如果为false,属性的值就不能被重写。
configurable: 如果为false,则任何尝试删除目标属性或修改属性性以下特性(writable, configurable, enumerable)的行为将被无效化。
enumerable: 是否能在for...in循环中遍历出来或在Object.keys中列举出来。
set:一旦目标属性被赋值,就会调回此方法。
get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。
注:当使用了getter或setter方法,不允许使用writable和value这两个属性
举个栗子(数据劫持):
// 劫持
function hijack(data) {
if (!data || typeof data !== 'object') {
return;
}
// 拿到对象里的每个key 和 value
Object.keys(data).forEach(item => {
// item:key data[item]:value
defineProperty(data, item, data[item]);
});
}
function defineProperty(obj, key, value) {
// 如果value是个对象则调用 hijack重新遍历(对象嵌套对象)
hijack(value);
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function () {
console.log('只要访问了该属性,我就会执行');
return value;
},
set: function (newValue) {
if (value === newValue) {
return
}
console.log('更新了!', value + '->' + newValue);
value = newValue;
}
});
}
var obj = {
a: 1,
b: 2
}
hijack(obj);
这个是控制台的结果: