Vue源码解析之数据响应系统的使用(11)

首先是一个if...else 判断,hasProto定义在core/util/env.js文件中。

// can we use __proto__?
export const hasProto = '__proto__' in {}

判断当前环境是否可以使用对象的 __proto__ 属性, 该属性在IE11及更高版本中才能使用。

如果条件为true的话,调用protoAugment方法, 传递了两个参数,一个是数组实例本身,一个是arrayMethods(代理原型)。

/**
 * Augment a target Object or Array by intercepting
 * the prototype chain using __proto__
 */
function protoAugment (target, src: Object) {
 /* eslint-disable no-proto */
 target.__proto__ = src
 /* eslint-enable no-proto */
}

该方法的作用就是将数组实例的原型指向代理原型。这样当数组实例调用变异方法的时候就能先走代理原型重定义的方法。我们看一下arrayMethods的实现,它定义在core/observer/array.js文件中:

import { def } from '../util/index'

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

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

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {
 // cache original method
 const original = arrayProto[method]
 def(arrayMethods, method, function mutator (...args) {
 const result = original.apply(this, args)
 const ob = this.__ob__
 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()
 return result
 })
})

这是这个文件的全部内容,该文件只做了一件事,就是导出arrayMethods对象。

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

arrayMethods是以数组的原型为原型创建的对象。

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

这是定义了数组的变异方法。

接着for循环遍历变异方法,用def在代理原型上定义了与变异方法同名的方法。

methodsToPatch.forEach(function (method) {
 // cache original method
 const original = arrayProto[method]
 def(arrayMethods, method, function mutator (...args) {
 const result = original.apply(this, args)
 const ob = this.__ob__
 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()
 return result
 })
})

      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/19.html