ES6数据劫持proxy&reflect

ES5数据劫持

VUE的双向数据绑定的基础知识。

对对象的监测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
var oDiv = document.getElementById('show');
var oInput = document.getElementById('demo');

var oData = {
valueObj: {
value: 'duntengOG',
name: 'haha'
},
sex: 'aaa'
};


oInput.oninput = function () {
oData.value = this.value;
};


function upDate () {
oDiv.innerText = oData.valueObj.value;
}

upDate();

// 监控对象的某个属性是否发生改变
function Observer (data) {
if (!data || typeof data != 'object') {
return data;
};
// for (var prop in data) {

// }
Object.keys(data).forEach(function (key) {
definedRective(data, key, data[key]);
});
}

function definedRective (data, key, val) {
// AO
Observer(val);//针对对象属性的监测
Object.defineProperty(data, key, {
get () {
// console.log('get');
return val;
},
set (newValue) {
if (newValue == val) return;
val = newValue;
upDate();
}
})
};

Observer(oData);

console.log(oData.valueObj);
oData.valueObj.value = 'haha';

有个缺点就是如果之后该对象又新增了一个属性,则Observer是无法监测到的

对数组的监测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let arr = [];
let {push} = Array.prototype;//解构赋值定义一个push函数

function upData () {
console.log('更新后的数组arr为:'+arr);
};

Object.defineProperty(Array.prototype, 'push', {
value: (function () {
return (...arg) => {
push.apply(arr, arg);
upData();
}
})()
});


arr.push(1, 2);

ES6数据劫持

proxy & reflect

ES6中新增的proxy&reflect实现了数据劫持的功能,是ES6在较底层实现的功能所以不用babel转换。代码量比ES5的少了,而且不会出现像ES5那样在程序后续过程中新增监测对象属性监测不到的情况。但是proxy&reflect的兼容性不好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 

let oData = {
val: 'duntengOG',
_val: 'aaaa'//我们定义的私有属性,不想让别人知道
}

let oProxyData = new Proxy(oData, {
set(target, key, value, receiver) {
// console.log(target, key, value, receiver); target就是代理对象,key即操作的属性
Reflect.set(target, key, value);
upDate();
},
get(target, key, receiver) {
// console.log(target, key, receiver);
return Reflect.get(target, key);
},
// 还有has、deleteProperty。。。等操作,但不是很常见
has(target, key) {
return key.indexOf('_') != -1 ? false : key in oData;
},
deleteProperty() {

}
});
// 读写 控制
console.log(oProxyData.val);
oProxyData.val = 10;

function upDate() {
console.log('更新了')
}

oProxyData.name = 20;

// console.log( delete oProxyData.val );

(完)

转载请注明出处。