Underscore.JS 之 消灭for循环

UnderScore.JS是一款对JavaScript内置对象具有高效多种处理方法的JS库文件。

UnderScore LOGO

文档

官方网站

安装

安装Underscore.JS的方法如下:

  • Node.js npm install underscore --save
  • bower bower install underscore --save

上面的命令行指令中,--save的作用是直接把引用写到 package.json 以及 index.html 中,如果不加的话则须手动修改文件。

还有其他一些不常用的安装方法,有需要可用参考官方文档。

安装完成后,可用使用 npm listbower list 来确保安装的正确性,并确保在 index.html 中具有相应的引用。


使用介绍

在本文中,将会介绍如何用简单的UnderScore.JS函数来替代原有的for循环编程习惯,可以极大减少代码量。

当然,UnderScore.JS的实际可用功能远远不止这一点。

现在,我们来构造一个简单的通讯录如下,命名为 phone_list ,实际上也可适用于任何的数组或者对象:

[{name:'张三',phone:'13311111111',from:'北京'},
{name:'李四',phone:'13322222222',from:'上海'},
{name:'王二',phone:'13333333333',from:'广州'},
{name:'刘一',phone:'13344444444',from:'北京'},
{name:'赵零',phone:'13355555555',from:'上海'}]

案例一

假设我现在需要给“王二”打电话,需要知道“王二”的手机号码,而数组本身没有直接的查询功能,所以一般的方法是:

for(var i=0; i<phone_list.length; i++) {
	if(phone_list[i].name == '王二') {
		return phone_list[i].phone;
	}
}
return undefined;

上面我们构造了一个for循环,逐项查找 name 字段,找到“王二”时返回其手机号。就算法复杂度而言,在没有数据库的情况下,对对象数组的操作只能时顺序查找,并没有什么问题。但是,这样写有很多没有必要的内容,对于各种方法需要构造各种各样的for循环。那么有没有什么办法能够直接一个函数就完成上述功能呢?Underscore就给了我们这样一个机会。

使用UnderScore.JS方法的代码如下:

return _.findWhere(phone_list, {name: "王二"}).phone;

_.findWhere 函数具有两个参数,第一个为需要查找的列表(数组),第二个为查找的条件(对象),返回值为列表中找到的第一个满足条件的元素。本例中为“王二”的通讯录对象,然后通过 .phone 获取其电话号码。

原本的6行代码现在只需要1行完成,可用大大减少不必要的工作量;同时代码的可读性也大大增加,减少不必要的错误概率。

案例二

假如我突然心血来潮,要把通讯录里面所有人的手机号码前面都加上 +86 ,先不考虑有木有这样的强迫症患者,现在大多数人首先想到的应该还是for循环吧?是的,for循环确实基本是万能的,便利一个数组当然也是小事一桩:

for(var i=0; i<phone_list.length; i++) {
	phone_list[i].phone = "+86".concat(phone_list[i].phone);
}

for循环的忠实支持者可能会说,这次我在for循环里面只用了一行就搞定了~

当然,使用Underscore.JS同样能够做到:

_.each(phone_list, function (element) {
	element = "+86".concat(element.phone);
});

_.each() 函数具有两个参数,第一个是需要遍历的对象,第二个是对其中每个元素的操作内容。

总的来说这里二者的代码量相当,当相对而言后者还是要略显简介~

案例三

有一天我突然到了北京,然后我想知道有那些朋友是北京的(连是哪的都不知道还好意思叫朋友么...)。如果使用传统的for循环,思路就是新建一个数组,如果是北京的就放进去,代码如下:

var result = [];
for(var i=0; i<phone_list.length; i++) {
	if(phone_list[i].from == '北京') {
		result.push(phone_list[i]);
	}
}
return result;

看了上面的例子大家应该发现,一旦需要用到 if ,for循环就输定了...

使用Underscore.JS的代码明显要短很多:

return _.where(phone_list, {from: "北京"};

_.where() 的用法和 _.findWhere 相同,不同的是前者返回所有满足条件的元素构成的数组,而后者只返回第一个满足的元素。

案例四

如果我还是想设定一些条件来查找通讯录,但条件又不是具有某一键值对,那又该怎么办呢?

还是老样子,先来for循环的方法:

var result = [];
for(var i=0; i<phone_list.length; i++) {
	if(phone_list[i].phone.substring(0,3) == '133') {
		result.push(phone_list[i]);
	}
}
return result;

这个我们当然也还是可以用Underscore.JS来解决:

return _.filter(phone_list, function (person) {
	person.phone.substring(0,3) == '133'
});

_.filter() 函数中,相当于把 _.where() 需要满足的键值对换成人为设定的布尔函数,返回的是布尔函数为真的所有元素构成的集合。

本文的内容到这里就结束了,但是Underscore.JS的使命才刚刚开始。看完这些,你是否已经对Underscore.JS心动了呢?


本站地址: http://trotyl.github.io/

posted @ 2014-07-25 10:16  Trotyl  阅读(672)  评论(0编辑  收藏  举报