如何写 JS 的链式调用 ---》JS 设计模式《----方法的链式调用

1.以$ 函数为例。通常返回一个HTML元素或一个元素集合。

代码如下:

function $(){
    var elements = [];
    for(var i=0;i<arguments.length;i++){
     var element = argument[i];
     if(typeOf element == "String") {
        element = document.getElementById(element);
     }  
     if ( arguments.length === 1) {
       return element;
     }
     elements.push(element);
  }  
  return elements;
}

但是;如果把这个函数改造为一个构造器,把那写元素作为数组保存在一个实例属性中,并让所有

定义在构造器函数的prototype属性所指对象的方法都返回泳衣调用方法的那个实例的引用,那么它

就有了进行链式调用的能力。

首先,需要把$函数改为一个工厂方法,负责支持链式调用的对象,这个函数应该能接受元素数组形式的参数,以便于我们能够使用与原来一样的公共借口。

代码如下:

(function(){
   //私有
  function _$(els){
    this.elements = [];
    for(var i=0;i<els.length;i++)  {
      var element = els[i];
      if(typeOf element === "String") {
         element = document.getElementById(element);
      }
       this.elements.push(element);
    }    
//共有借口 仍然一样
  window.$ = function() {
     return new _$(arguments);
   }

})()

由于所有对象都会继承其原型对象的属性和方法,所以我们可以让定义在原型对象中的几个方法都返回用于调用方法的实例对象的引用,这样就可以对那些方法进行链式调用---》有了这一点《-----我们就可以动手在_$这个私有构造函数的prototype对象中添加方法,用于实现链式调用;

代码如下:

(function() {
// 私有构造器
  function _$(els){
    this.elements = [];
    for(var i = 0;i<els.length;i++){
     var element = els[i];
     if(typeOf element === "String") {
       element = document.getElementById(element);
      }
     this.elements.push(element);
    }
// 在原型中添加属性和方法
   _$.prototype = {
       each: function(){
          for(var i = 0;i<this.elements.length;i++){
             fn.call(this,this.elements[i]);
           }
          return this;
        },
        setStyle: function(prop, val) {
          this.each(function(el){
             el.style[prop] = val;
           });
          return this;
        },
        show: function() {
          var that = this;
          this.each(function(el){
            that.setStyle('display', 'block');
           });
          return this;
         },
        addEvent: function(type, fn){
          var add = function(el){
              if(window.addEventListener) {
                el.addEventListener(type, fn,false);
               } else if(window.attachEvent) {
                 el.attachEvent(on + 'type', fn);
               }
             this.each(function(el){
                add(el);
              });
            }
           return this;
         }
    };
  window.$ = function() {
    return new _$(arguments);
   }

}



})

到目前为止,该类的每一个方法的最后一行都是以 return this 结束。 这会将用以调用方法的对象传给调用链上的下一个方法。支持链式调用的接口带来的可能性是无穷的。现在你就可以实现代码的链式调用了

$(window).addEvent('load',function(){
   $('xxx').show().setStyle().addEvent('click',function(){
   //想写的代码 
    }) 
})

ps: 到此为止,你基本上可以理解JS 或者 Jquery是如何实现了方法的链式调用。。。

     如果觉得文章不错,欢迎打赏

下一篇将介绍如何设计一个支持方法链式调用的JS 库

posted @ 2017-01-04 17:47  Terre  阅读(1881)  评论(0编辑  收藏  举报

风光无限好