实现数组响应式主要有以下三个步骤。
- 找到数据原型
- 覆盖那些能够修改数组的更新方法
[push,pop,shift,unshift,splice,sort,reverse]
,使其可以通知更新 - 将得到的新的原型设置到数据实例原型上
//第一步,找到数据原型
const originalProto=Array.prototype
//备份,进行修改,不能直接修改原型
const arrayProto=Object.create(originalProto)
//第二步 覆盖那些能够修改数组的更新方法
const arrayMethods=['push','pop','shift','unshift','splice','sort','reverse'];
arrayMethods.forEach(method=>{
const original = arrayProto[method];
def(arrayMethods, method, function() {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
var result = original.apply(this, args);
var ob = this.__ob__;
var inserted;
console.log(method)
switch (method) {
case 'push':
case 'unshift':
inserted = args;
break
case 'splice':
inserted = args.slice(2);
break
}
if (inserted) { ob.observeArray(inserted); }
// notify change 使其可以通知更新
ob.dep.notify();
return result
});
})
//第三步 将得到的新的原型设置到数据实例原型上
// 辨别类型
if (Array.isArray(value)) {
var hasProto = '__proto__' in {};
if(hasProto){
value.__proto__=arrayMethods;
}else{
const arrayKeys = Object.getOwnPropertyNames(arrayMethods);
copyAugment(value, arrayMethods, arrayKeys);
}
this.observeArray(value);
// todo
} else {
this.walk(value)
}
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
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
具体实现代码在 github
上有详细代码。github地址 (opens new window)