Vue源码好用的函数

1、cached

/**
 * Create a cached version of a pure function.
 */
function cached (fn) {
  var cache = Object.create(null);//es6语法,创建一个空对象
  return (function cachedFn (str) {
    var hit = cache[str];
    console.log(cache)  //加的代码,打印cache,观察变化
    return hit || (cache[str] = fn(str)) //如果hit有值就返回hit,没有返回fn的返回值,并且将该值赋给cache对象
  })
}

然后咱们写个小例子来调用

var fn=(val)=>{
    return val;
}//一个返回自身输入的函数
var rsFn=cached(fn);//这变其实是返回的一个function
rsFn(1) //打印{}
rsFn(2) //打印{1:1}
rsFn(1) //当你再次调用时,{1:1}其实已经被缓存下来了,用了闭包,所以cache对象会一直存在于内存中
//这时候取1,就会直接去取出cache对象中的值,而不会再次调用方法。

从而就实现了一个函数式的方法,只要你想要将你缓存,输入输出的函数,作为参数传入,就会为你实现一个缓存数据的功能。

2、polyfillBind

每次加元素计算数组长度(这里以数组数据类型为例)

/* istanbul ignore next */
function polyfillBind (fn, ctx) {
  function boundFn (a) {
    var l = arguments.length;
    console.log(ctx) 打印ctx,进行观察
    return l
      ? l > 1
        ? fn.apply(ctx, arguments)//多个对参数数组apply,返回总长度
        : fn.call(ctx, a)//一个参数就直接call,返回总长度
      : fn.call(ctx) //没有新参数,就返回原长度
  }

  boundFn._length = fn.length;
  return boundFn
}
var rsFn=polyfillBind(Array.prototype.push,[])//传入一个初始数组对象
rsFn(1) //[] // 1 因为数组打印在前,所以值都会滞后一步
rsFn(2) //[1]  //2
rsFn([1,2]) //添一个数组//[1, 2]
rsFn() // [1, 2, Array(2)]
rsFn() // [1, 2, Array(2)]

3、looseEqual

对对象的浅相等进行判断

  /**
   * Check if two values are loosely equal - that is,
   * if they are plain objects, do they have the same shape?
   */
  function looseEqual (a, b) {
    if (a === b) { return true }
    var isObjectA = isObject(a);
    var isObjectB = isObject(b);
    if (isObjectA && isObjectB) {
      try {
        var isArrayA = Array.isArray(a);
        var isArrayB = Array.isArray(b);
        if (isArrayA && isArrayB) {
          return a.length === b.length && a.every(function (e, i) {
            return looseEqual(e, b[i])
          })
        } else if (a instanceof Date && b instanceof Date) {
          return a.getTime() === b.getTime()
        } else if (!isArrayA && !isArrayB) {
          var keysA = Object.keys(a);
          var keysB = Object.keys(b);
          return keysA.length === keysB.length && keysA.every(function (key) {
            return looseEqual(a[key], b[key])
          })
        } else {
          /* istanbul ignore next */
          return false
        }
      } catch (e) {
        /* istanbul ignore next */
        return false
      }
    } else if (!isObjectA && !isObjectB) {
      return String(a) === String(b)
    } else {
      return false
    }
  }

4、解读Dep,Observer和Watcher

Vue实例化一个对象的具体过程如下:

  • 新创建一个实例后,Vue调用compile将el转换成vnode。
  • 调用initState, 创建props, data的钩子以及其对象成员的Observer(添加getter和setter)。
  • 执行mount挂载操作,在挂载时建立一个直接对应render的Watcher,并且编译模板生成render函数,执行vm._update来更新DOM。
  • 每当有数据改变,都将通知相应的Watcher执行回调函数,更新视图。当给这个对象的某个属性赋值时,就会触发set方法。set函数调用,触发Dep的notify()向对应的Watcher通知变化。Watcher调用update方法。

在这个过程中:

  • Observer是用来给数据添加Dep依赖。
  • Dep是data每个对象包括子对象都拥有一个该对象, 当所绑定的数据有变更时, 通过dep.notify()通知Watcher。
  • Compile是HTML指令解析器,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。
  • Watcher是连接Observer和Compile的桥梁,Compile解析指令时会创建一个对应的Watcher并绑定update方法 , 添加到Dep对象上。

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值