vue学习,简单手写实现数组的变化监测

vue学习,简单手写实现数组的变化监测

vue的对象Object的监听是通过 js对象原型上的 Object.defineProerty()方法设置 settergetter 来实现的,但是数组 Array没有 这个方法,所以方法有所不同,但是万变不离其宗,对于变化的监测原理还是相似的,就是在获取数据时收集依赖,在数据变化时通知依赖更新。首先思考一下我们在vue中使用 数组时的方法:

data(){
    return{
        arr:[1,2,3]
    }
}

​ 可以看出数组arr还是定义在了一个对象中,所以要用到这个数组的时候,必然会触发arrgetter,所以我们可以知道数组什么时候会读取,但是要知道数组什么时候发生变化,需要对操作的数组的方法拦截,经过整理我们知道js改变数组自身内容的方法有7个:push,pop,shift,unshift,splice,sort,reverse,我们拿push方法举例。

// 原生push方法
let arr = []
arr.push('111')
// vue 拦截数组原理
Array.prototype.newPush = function(val){
    console.log('数组被修改了')
    this.push(val)
}
arr.newPush('111')
 接下来实现数组所有方法的拦截
const arrayProto = Array.prototype
// 创建一个对象作为拦截器
export const arrayMethods = Object.create(arrayProto)

// 改变数组自身内容的7个方法
const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {
  const original = arrayProto[method]      // 缓存原生方法
  Object.defineProperty(arrayMethods, method, {
    enumerable: false,
    configurable: true,
    writable: true,
    value:function mutator(...args){
      const result = original.apply(this, args)
      return result
    }
  })
})

​ 在上面的代码中,首先创建了继承自Array原型的空对象arrayMethods,接着在arrayMethods上使用object.defineProperty方法将那些可以改变数组自身的7个方法遍历逐个进行封装。最后,当我们使用push方法的时候,其实用的是arrayMethods.push,而arrayMethods.push就是封装的新函数mutator,也就是说,实标上执行的是函数mutator,而mutator函数内部执行了original函数,这个original函数就是Array.prototype上对应的原生方法

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容