# 数组更新检测实现原理

我们知道Vue官网说了

​ Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

那具体是怎么实现的呢,实际也是比较简单的:

# 第一步: 创建一个包囊上边方法的对象,并重写这些方法

const arrayProto = Array.prototype

const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];

// 这里之所以要用Array.prototype创建对象就是因为我们还要保留原始数组的特征
export default const arrayMethod = Object.create(arrayProto);

methods.forEach(method => {
  Object.defineProperty(arrayMethod, method, {
    writable: true,
    enumerable: false,
    configurable: true
    value: function mutator(...args) {
  	  const result = arrayProto[method].apply(this, args);
      let inserted
      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()
	  }   
  })
})
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

# 第二步:把数组的__proto__指向上边创建的对象

// 假设我们的数组就叫arr
arr.__proto__ = arrayMethod
1
2