vue源码之Array

目录

Vue中对Array和Object追踪方式的不同之处?

Object通过setter改变属性的值,所以我们利用getter时发送依赖收集,在setter时触发依赖更新,而且Vue将数据转换成响应式数据是在数据初始化时,对Object中之后的属性新增和删除操作,无法做到自动更新,而是通过vm. s e t 和 v m . set和vm. setvm.delete手动转换成响应式,并立即发出更新通知。

但是,一般在对数组的操作中,可以改变数组自身内容的方法有push、pop、shift、unshift、splice、sort、reverse七个。当我们给一个数组类型的属性赋值时,属性的setter函数会触发,从而通知更新。但是在使用push等一系列操作方法时,由于ES6之前,JS没有元编程能力,没有提供可以拦截原型方法的能力,所以,我们思考,如果能在用户使用这些方法操作数组时得到通知,那就达到了追踪的目的。

拦截原型

如何做到在操作这些原型方法时能得到通知呢?

对!就是拦截原型。

基本原理:用一个拦截器覆盖Array.prototype, 每当使用原型上的方法操作数组时,实际上执行的都是拦截器提供的方法,在拦截器中除了调用原生的方法操作数组外,还可以干点别的事,比如:通知依赖更新!

创建拦截器
  1. 编写拦截器
  • 定义需要拦截的原型方法集合 methodsToPatch
  var arrayProto = Array.prototype;
  // 创建一个新的空对象arrayMethods,并将原型指向Array.prototype
  var arrayMethods = Object.create(arrayProto);

  var methodsToPatch = [
    'push',
    'pop',
    'shift',
    'unshift',
    'splice',
    'sort',
    'reverse'
  ];
  • 方法重写
methodsToPatch.forEach(function (method) {
   
    // 缓存原始方法
    var original = arrayProto[method];
    // 方法重写,屏蔽了Array.prototype上的方法,同时内部调用Array.prototype上的原始方法
    def(arrayMethods, method, function mutator (...args) {
   

      var result = original.apply(this, args);
      
      // 占位符D1 :这里可以做些事:比如通知依赖更新...
      
      return result
    });
  });

function def (obj, key, val, enumerable) {
   
    Object.defineProperty(obj, key, 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值