JavaScript链式调用原理与实现方法详解

作者:纸飞机时间:2026-10-23 18:37:58浏览:485

本文深入解析JavaScript链式调用的核心原理,即通过方法返回当前对象实现连续调用。文章对比了普通调用与链式调用的代码差异,并详细演示了如何模仿jQuery库,通过定义私有类、扩展Function原型以及静态方法,构建支持链式调用的自定义对象模型,旨在简化代码编写并提升可读性。

链式调用概述

本文详细解析JavaScript中链式调用的实现机制,并提供具体代码示例供参考。

链式调用原理

1、什么是链式调用?

这一概念易于理解,例如:


$('text').setStyle('color', 'red').show();

普通函数调用与链式调用的核心区别在于:链式调用在方法执行完毕后,需返回当前调用该方法的对象(即return this)。

首先,我们观察普通函数的调用方式。

(1)创建一个简单的类:


//创建一个bird类
  function Bird(name) {
    this.name=name;
    this.run=function () {
    document.write(name+" "+"start run;");
        }
    this.stopRun=function () {
     document.write(name+" "+"start run;");
        }
    this.sing=function () {
      document.write(name+" "+"start sing;");
    }
    this.stopSing=function () {
      document.write(name+" "+"start stopSing;");
    }
  }

(2)常规调用方式如下:


 var bird=new Bird("测试");
  bird.run();
  birdbird.sing();
  bird.stopSing();
  bird.stopRun();

//结果为;测试 start run;测试 start sing;测试 start stopSing;测试 start run;

(3)总结:这种方式存在一个弊端,即需要多次重复引用同一个对象变量。

接下来,我们将上述代码改写为链式调用格式。

(1)在创建的简单类中,为每个方法添加return this,示例如下:


//创建一个bird类
  function Bird(name) {
    this.name=name;
    this.run=function () {
      document.write(name+" "+"start run;");
      return this;// return this返回当前调用方法的对象。
    }
    this.stopRun=function () {
      document.write(name+" "+"start run;");
      return this;
    }
    this.sing=function () {
      document.write(name+" "+"start sing;");
      return this;
    }
    this.stopSing=function () {
      document.write(name+" "+"start stopSing;");
      return this;
    }
  }

(2)使用链式调用(连缀方式):


var bird=new Bird("测试");
  bird.run().sing().stopSing().stopRun();//结果为;测试 start run;测试 start sing;测试 start stopSing;测试 start run;

(3)总结:此种方式产生的结果与普通调用一致,但其优势在于链式风格能简化代码编写,使代码更简洁易读,同时避免了重复使用对象变量。

模仿jQuery实现链式调用

2.模仿jquery的链式调用

第一步,定义一个包含参数的空对象。


(function(){
 //下划线:表示私有变量的写法
  function _$(els) { };//有参数的空对象
})()//程序启动的时候 里面的代码直接执行了

第二步,准备方法:在_$上定义一个onrReady方法。


(function(){

  //第一步,下划线:表示私有变量的写法
  function _$(els) { };//有参数的空对象
//第二步,准备方法 在_$上定义一个onrReady方法 _$.onrReady=function (fn) { //按要求把对象(_$)注册到window对象上 //对外开放的接口 window.$=function () { return new _$(arguments);//传递相应的方法调用参数 返回一可以使用function类原型上的方法的对象($("")=_$(参数)) } fn(); } } })()

第三步,为了扩展Function类的函数,我们定义一个静态函数。


Function.prototype.method=function (name,fn) {//(函数名称,函数本身)
   this.prototype[name]=fn;
   return this;//链式调用关键
};//这个函数的意思:为function对象增加函数,会用链式调用,链式调用有两个参数name,和fn

第四步,扩展类的相应方法:为链式对象增加jQuery库提供的操作函数。


(function(){
  //下划线:表示私有变量的写法
  function _$(els) { };//有参数的空对象
  //第二步,准备方法 在_$上定义一个onrReady方法
  _$.onrReady=function (fn) {
    //按要求把对象(_$)注册到window对象上  
    //对外开放的接口
    window.$=function () {
      return new _$(arguments);//传递相应的方法调用参数 返回一可以使用function类原型上的方法的对象($("")=_$(参数))
    }
    fn();
  }
//第四步 //扩展类的相应方法 链式的对象增加jquery库提供的操作函数 _$.method("AddEvent",function (type,fn) {//_$本身是一个function要继承原型链上的东西。 fn(); }).method("getEvent",function (fn,e) { fn(); }) })()

第五步,使用:需调用_$.onReady方法以返回对象,从而使用从Function类继承的原型方法。


(function () {
  // (1)下划线:表示私有变量的写法
  function _$(els) { };//有参数的空对象
  //(2)准备方法 在_$上定义一个onrReady方法
   // window.$=_$;
  _$.onrReady=function (fn) {
    //按要求把对象(_$)注册到window对象上  在任何地方都可以使用
    //对外开放的接口
    window.$=function () {//window 上先注册一个全局变量 与外界产生关系
      return new _$(arguments);//传递相应的方法调用参数 返回一可以使用function类原型上的方法的对象($("")=_$(参数))
    }
    fn();
  }
  //(4)扩展类的相应方法 链式的对象增加jquery库提供的操作函数
_$.method("AddEvent",function (type,fn) {//_$本身是一个function要继承原型链上的东西。
  fn();
}).method("getEvent",function (fn,e) {
  fn();
});
  //第五步,开始使用 ,需要调用_$.onready方法才可以返回对象使用从function类继承而来的原型上的方法
   _$.onrReady(function () {//$是绑定在Windows上的
    $("").AddEvent("click",function () {
      alert("click")
    })
  })

})()

上述综合代码如下:


//第三步,为了类(Function)能扩展函数,我们定义一个它的静态函数
Function.prototype.method=function (name,fn) {//(函数名称,函数本身)
   this.prototype[name]=fn;
   return this;//链式调用关键
};//这个函数的意思:为function对象增加函数,会用链式调用,链式调用有两个参数name,和fn

(function () {
  // 第一步,下划线:表示私有变量的写法
  function _$(els) { };//有参数的空对象
  //第二步,准备方法 在_$上定义一个onrReady方法
   // window.$=_$;
  _$.onrReady=function (fn) {
    //按要求把对象(_$)注册到window对象上 
    //对外开放的接口
    window.$=function () {
      return new _$(arguments);//传递相应的方法调用参数 返回一可以使用function类原型上的方法的对象($("")=_$(参数))
    }
    fn();
  }
  //第四步,扩展类的相应方法 链式的对象增加jquery库提供的操作函数
_$.method("AddEvent",function (type,fn) {//_$本身是一个function要继承原型链上的东西,所以可以使用method方法
  fn();
}).method("getEvent",function (fn,e) {
  fn();
});
  //第五步,开始使用,需要调用_$.onready方法才可以返回对象使用从function类继承而来的原型上的方法
   _$.onrReady(function () {//$是绑定在Windows上的
    $("").AddEvent("click",function () {
      alert("click")
    })
  })
})()

上述示例将$绑定到了window对象。若希望将$绑定到指定对象,可通过调整第二步和第五步实现,具体如下:


/**
 * Created by 与你在巅峰相会 on 2017/10/12.
 */

//第三步,为了类(Function)能扩展函数,我们定义一个它的静态函数
Function.prototype.method=function (name,fn) {//(函数名称,函数本身)
   this.prototype[name]=fn;
   return this;//链式调用关键
};//这个函数的意思:为function对象增加函数,会用链式调用,链式调用有两个参数name,和fn

(function () {
  // 第一步,下划线:表示私有变量的写法
  function _$(els) { };//有参数的空对象
  //第二步,准备方法 在_$上定义一个onrReady方法
  _$.onReady=function (obj,fn) {//obj传进来的对象
    if(obj){
      //按要求把对象(_$)注册到window对象上 
      //对外开放的接口
      obj.$=function () {
        return new _$(arguments);//传递相应的方法调用参数 返回一可以使用function类原型上的方法的对象($("")=_$(参数))
      }
    }else {
      //按要求把对象(_$)注册到window对象上  
      //对外开放的接口
      window.$=function () {
        return new _$(arguments);//传递相应的方法调用参数 返回一可以使用function类原型上的方法的对象($("")=_$(参数))
      }
    }
    fn();
  }
  //第四步,扩展类的相应方法 链式的对象增加jquery库提供的操作函数
_$.method("AddEvent",function (type,fn) {//_$本身是一个function要继承原型链上的东西,可以直接使用method方法
  fn();
}).method("getEvent",function (fn,e) {
  fn();
});
  //第五步,开始使用,需要调用_$.onready方法才可以返回对象使用从function类继承而来的原型上的方法
   var com={};
  _$.onReady(com,function () {//$是绑定在Windows上的
    com.$("").AddEvent("click",function () {
      alert("click")
    })
  })
})()

绘制简图以辅助理解上述过程及思路:

链式调用概述

感兴趣的朋友可使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

作者最新文章