本文深入解析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程序设计有所帮助。