12

通过实现链式调用来理解

   链式调用是我们平常经常会用到,比如JQuery中的$('id').eq(0), 还有lodash中的_.chain().push()。 这些都是平常会用到的,但是都是已经封装好的,我们知道用起来很方便却不知道实现的原理是什么。
   其实呢它并没有很神秘,只不过是一种语法招数,它能让你通过重用一个初始操作来达到用少量代码表达复杂操作的目的。

通过例子来分析链式调用

  其实链式调用就是让一个类的每个方法都返回this值,从而达到链式调用
  首先创建一个构造函数,把那些元素作为数组保存在一个实例属性中,并把所有定义在构造器函数的 prototype属性指向对象中的方法都返回用以调用方法的那个实例的引用,那么它就具有了进行链式调用的能力
我们来看一下这段例子

 $('div')
      .eq(0)
      .css('width', '200px')
      .show();

这其实就是一段简单JQuery代码,选择第一个div设置css样式,然后将它显示出来。

    function JQuery(selector) {
      this.elements = document.querySelectorAll(selector);
    }
    
    JQuery.prototype = {
      eq: function(index) {
        this.elements = [this.elements[index]]
        return this;
      },
      css: function(prop, value) {
        this.elements.forEach(function(el) {
          // 动态设置属性
          el.style[prop] = value;
        })
        return this;
      },
      show: function() {
        this.css('display', 'block')
        return this;
      },
    }

这段代码很明显在prototype上的三个函数都返回了this,在函数中实现对应的功能也是直接使用this来获取值,然后修改this中的值再返回this,这样在下次调用的时候还是JQuery对象,从而实现了链式调用。
  既然函数都是在原型链上,那么肯定需要创建一个对象才能去调用函数吧,而我们并没看到new JQuery,而且也没有看见$符号,那怎么才能使用呢。

window.$ = function(selector) {
  return new JQuery(selector);
}
$('div')
  .eq(0)
  .css('width', '200px')
  .show();

直接用一个匿名函数返回一个new JQuery()的对象,然后赋值给$并挂载到全局上,这样就实现了一个JQuery的链式调用了。


AMCode
170 声望30 粉丝

学无止境