链式方法,或者也被成为级联方法,是一种在一个对象上使用一条连续的代码来重复调用不同方法的技巧。这种技巧在jQuery和其他一些JavaScript库中很流行,它甚至也是一些JavaScript原生方法的内在特性,比如常见的字符串方法。
链式方法的表达形式如下所示:
$('#wrapper').fadeOut().html('Welcome, Sir').fadeIn();
或者:
str.replace('k','R').toUpperCase().substr(0,4);
这种写法是如此的美妙以致于我们无法抗拒使用它。
下面让我们轻松愉快的花上20分钟来学习怎样在我们的代码中创建这种美妙的方法,相信我,要是不这样做你一定会后悔的。这种方法学习起来轻松且毫不费力,因为链式方法在JavaScript中实现起来实在是太直观了。我们只需要在每个方法中返回this(那个我们希望子序列方法作用的对象)即可。我们先来快速的学会这种方法然后再回头来写我们手边的代码。
让我们在一个对象中创建我们所有的链式代码,改对象中还存储这我们需要使用的所有数据。需要注意的是在现实世界的app中,我们一般在一个数据库中存储数据,但是在这我们仅仅把数据存放在一个变量中。
// 数据存放:
var usersData = [
{firstName:"tommy", lastName:"MalCom", email:"test@test.com", id:102},
{firstName:"Peter", lastName:"breCht", email:"test2@test2.com", id:103},
{firstName:"RoHan", lastName:"sahu", email:"test3@test3.com", id:104}
];
// 一个函数功能如其名的函数:
function titleCaseName(str)
{
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
// 我们创建的带有链式方法的对象
var userController = {
currentUser:"",
findUser:function (userEmail) {
var arrayLength = usersData.length, i;
for (i = arrayLength - 1; i >= 0; i--) {
if (usersData[i].email === userEmail) {
this.currentUser = usersData[i];
break;
}
}
return this;
},
formatName:function () {
if (this.currentUser) {
this.currentUser.fullName = titleCaseName (this.currentUser.firstName) + " " + titleCaseName (this.currentUser.lastName);
}
return this;
},
createLayout:function () {
if (this.currentUser) {
this.currentUser.viewData = "<h2>Member: " + this.currentUser.fullName + "</h2>"
+ "<p>ID: " + this.currentUser.id + "</p>" + "<p>Email: " + this.currentUser.email + "</p>";
}
return this;
},
displayUser:function () {
if (!this.currentUser) return;
$(".members-wrapper").append(this.currentUser.viewData);
}
};
有了上面定义的这些链式方法,现在我们可以像下面的代码一样执行这些富于表现力的方法了(像在jQuery中那样):
userController.findUser("test2@test2.com").formatName().createLayout().displayUser();
代码在JSBin中的链接:http://jsbin.com/erewat/1/edit
为什么在JavaScript中使用级联
-
不需要为过程中的每一步创建临时变量。例如,没有级联的话我们的代码如下所示:
var aUser = userController.findUser("test@test.com"); var formatUserName = aUser.formatName(); var layoutHTML = formatUserName.createLayout(); userController.displayUser(layoutHTML);
-
我们的代码更富于表现力(每一行都能清晰简洁的表达出它究竟在做什么)更简洁,尤其是当方法的名字使用动词定义时。
-
我们的代码更具有可维护性因为我们拥有简单,干净指向明确的方法。
- 总之,比起其他方法,链式代码更容易去阅读,更容易输入并且更容易理解。
链式方法在JavaScript中怎样运行?
放每一个方法返回this时,整个对象(调用方法的对象)被返回。整个执行过程像下面的代码一样往前进:
//使用userController对象来执行findUser方法
userController.findUser("test@testdd.com")
因为我们在userController对象上执行findUser方法,也因为findUser对象返回“this”(调用该方法的对象),整个userController对象被返回并传递给了链中的下一个方法。主要是由于findUser方法中的“this”关键字包含了调用它的对象的值。
因此,接下来的一步是:
userController.formatName();
类似的,formatName方法返回了userController对象,因此正像我们所预期到的,接下来是:
userController.createLayout();
然后是:
userController.displayUser();
这个过程中的每一步,我们都反悔了userController对象并在它上调用方法。
结束语
这可能是目前为止我所写过的最短的文章了。但是我真心希望它和其他文章一样对你有帮助,你可以马上在你的JavaScript代码中开始使用级联方法,写出更具表现力更美妙的代码。
如果你发现了任何的bug,请马上通知我。
谢谢你的阅读。