Backbine.js实战第二章----Underscore

1.Underscore对象封装

Underscore没有对原生JavaScript对象进行封装,而是调用_()方法进行封装,一旦封装完成,原生JavaScript对象便成为一个Underscore对象。也可以通过Underscore对象的value()方法获取原生JavaScript对象中的数据。

var data = {
		name:'皮卡丘',
		email:'12345@qq.com'
	}
var object = _(data);//封装成Underscore对象
alert(object.value().name+"---"+object.value().email);


在上述代码中,先定义了一个原生JavaScript对象data,该对象中包含name、email两项属性,并设置了相应的属性值;然后,通过_()方法将原生的data对象转成一个名为"object"的Underscore对象;最后,在网页中弹出Underscore对象object调用value()方法获取原生JavaScript对象data中两项属性值的内容。


一旦使用_()方法封装成Underscore对象之后,就能通过value()方法访问封装前的原生JavaScript数据,还可以直接使用Underscore库中现存的函数,如下代码所示。

var arr = [15,26,37];
var obj = _(arr);//封装成Underscore对象
alert("最大:"+obj.max()+";最小:"+obj.min());

在上述代码中,先定义一个名为"arr"的数组,然后通过_()方法将数组转成一个名为“obj”的Underscore对象,最后obj对象调用Underscore库中的max()和min()函数在网页中弹出数组的最大和最小元素值。


2.2集合

1.each()和map()函数

Underscore中的each()和map()函数有一个共同特征,就是根据一定的条件遍历集合中的每个元素。它们又有区别,each()函数在操作时,只是执行按照过滤条件遍历每个列表元素的动作,该动作并无返回内容;而map()函数在操作时,不仅按照过滤条件执行遍历元素的操作,而且返回一个新的过滤后的集合内容,接下来进行逐个进行说明。

(1).each()函数

调用格式:

_,each(list,iterator,[context])

该函数的功能是:根据iterator迭代器提供的过滤条件,遍历list列表中的每一个元素,每遍历一次,产生一个迭代函数。此外,iterator迭代器还可以与可选项context上下文对象绑定。示例如下。

_.each([1,2,3,4,5,6,7],function(n){
	if(n%2){
		console.log(n);
	}
});

(2).map()函数

调用格式:

_.map(list,iterator,[context])

该函数的功能是:根据iterator迭代器中的函数,遍历list列表中的每一个元素,在完成列表元素遍历之后,该函数将返回一个数组对象。示例如下。

var arr = _.map([1,2,3,4,5,6,7],function(n){
	if(!(n%2)){
		return n;
	}
});
for(var p in arr){
	console.log(arr[p]);
}

在上述代码中,先由map()函数通过iterator迭代器从list列表中返回一个偶数数组arr。在arr数组中,虽然iterator迭代器使用了过滤条件,但返回的arr数组中元素的总数量与原列表一样。如果list列表中存在不符合iterator迭代器中条件的元素,在arr数组中将使用"undefined"来表示这些元素的值,以确保返回的arr数组与原列表中元素总数量保持一致。


总结:

each()和map()函数都是借助iterator迭代器遍历list列表中的每个元素,each()仅是按照iterator迭代器的规则操作list列表中的全部元素,函数本身并不返回数据;而map()函数不仅按照iterator迭代器的规则操作元素,而且返回一个新的数组,这就是两个函数间最大的区别。


无论each()或map()函数,如果参数list列表是一个JavaScript对象,iterator迭代器遍历时的参数则变为(value,key,list)。示例如下。

var obj = {
	a:'1',
	b:'2',
	c:'3'
};
_.each(obj,function(v,k,obj){//注意第一个参数是value,第二个参数才是key
	return console.log(k+"->"+v);
});


在上述代码中,先定义一个名为obj的JSON对象,它的内部含有3个属性a,b,c,并对应相应的属性值,然后使用each()函数操作对象中的属性。由于此时list列表参数是一个对象,因此,iterator迭代器中自定义的函数参数变为(v,k,obj),并在函数体中使用console.log方法输出对象中属性名称和对应的属性值。




2.find()和filter()函数

find()和filter()都属于查找或过滤性函数,都是在指定的列表或对象中,寻找符合iterator迭代器中自定义函数规则的元素项。如果找到,find()函数返回首个与条件相符的元素值;如果没有找到,则返回"undefined"。而在filter()函数中,如果找到,则返回一个与条件相符的数组;如果没有找到,则返回一个空数组。接下来我们逐一进行介绍。


(1).find()函数

调用格式:

_.find(list,iterator,[context])

该函数的功能是:根据iterator迭代器中的自定义函数条件,在list列表中查找符合条件的第一个元素项,如果找到,返回第一个元素项,否则返回"undefined"。示例如下。

var blnfind = _.find([2,4,6,8,10,12],function(n){
	return (!(n%2==0));
});
console.log(blnfind==undefined?"未找到":blnfind);

上述代码中,find()函数的iterator迭代器参数中,查找条件为"!(n%2==0)",即查找参数list列表中的奇数元素。如果找到,在控制台中输出首个符合查找条件的元素项,否则输出"未找到"的字样。由于上述代码中的list列表中不存在奇数项,因此将会输出"未找到"字样。


(2).filter()函数

调用格式:

_.filter(list,iterator,[context])

该函数的功能是:根据iterator迭代器中的自定义函数条件,在list列表中过滤符合条件的元素项。如果找到,则返回含有元素项的数组;如果没有找到,则返回一个空数组。示例如下。

var arrfind = _.filter([1,4,3,6,5,8],function(n){
	return (!(n%2==0));
});
console.log(arrfind.length!=0?arrfind:"未找到");

在上述代码中,在filter()函数的iterator迭代器参数中,过滤条件为"!(n%2==0)",即过滤参数list列表中的奇数元素,其中arrfind为过滤后返回的结果值。如果“arrfind.length!=0”成立,表示找到了,为控制台中输出全部符合过滤条件的元素项,否则输出“未找到”的字样。

3.max()和min()函数

(1).max函数

调用格式:

_.max(list,[iterator],[context])

该函数的功能是:返回list列表中的最大值。示例如下。

var arr = [1,2,3,4,5];
console.log("最大值:"+_.max(arr));


(2).min函数

调用格式:

_.min(list,[iterator],[context])

该函数的功能是:返回list列表中的最小值。示例如下。

var stu = [
	{name:'张三',score:60},
	{name:'李四',score:40},
	{name:'王五',score:80},
];
var min = _.min(stu,function(n){
	return n.score;
});
console.log("最小分数值姓名为:"+min.name);

在上述代码中,stu是一个JSON格式的数组,在使用min()函数获取该数组最小值时,增加了可选项参数iterator迭代器。该iterator迭代器是一个返回数组中score属性值的自定义函数,当执行min()函数时,先运行iterator迭代器中的自定义函数,返回一个包含数组中全部score属性值的新list列表,再从该列表中获取最小分数值。由于“李四的分数值最小,浏览器的控制台中将输出“李四字样。


4.sortBy()和groupBy()函数

(1).sortBy函数

调用格式:

_.sortBy(list,iterator,[context])

该函数的功能是:返回一个按升序排列的副本列表。排序的规则可以是iterator迭代器中自定义的函数,也可以是一个与元素属性相关的字符串,如“length”。示例如下。

var stu = [
	{name:'张三',score:60},
	{name:'李四',score:40},
	{name:'王五',score:80},
];
var sort = _.sortBy(stu,function(n){
	return n.score;
});
for(var p in sort){
	console.log(sort[p].name+"->"+sort[p].score);
}

在上述代码中,执行sortBy()函数排序后,获得一个按分数升序排列的副本列表对象,并将该对象保存至sort变量中,然后通过for语句将排序后的各元素内容输出至浏览器控制台中。

(2).groupBy()函数

调用格式:

_.groupBy(list,iterator,[context])

该函数的功能是:将list列表按iterator迭代器中自定义的函数或一个元素属性相关的字符串进行分组分割,分割后得到多个子列表。示例如下。

var stu = [
	{name:'张三',score:60},
	{name:'李四',score:40},
	{name:'王五',score:80},
];
var group = _.groupBy(stu,function(n){
	return n.score>60;
});
console.log(group);

在上述代码中,通过iterator迭代器中的自定义函数,对stu对象中的“score”元素按大于60的规则进行分组,然后在浏览器的控制台中输出分组后的对象group。

从上图中可以清楚地看出,输出的group对象根据过滤条件(大于60)被分割成false和true两个部分,false部分是包含两个元素的列表对象,true部分则是包含一个元素的列表对象。


2.3数组

2.3.1first()和last()函数

在Underscore中,first()和last()是处理数组最常用的两个函数。前者可以获取数组中的首个元素或指定位数的前面数组,后者可以返回数组中的最后一个元素或指定位数的后面数组。接下来我们逐一进行说明。


1.first()函数

调用格式:

_.first(array,[n])

该函数的功能是:返回数组的第一个元素。如果设置可选项n的值,将返回一个包含前n项元素的新数组。示例如下。

var stu = [
	{name:'张三',score:60},
	{name:'李四',score:40},
	{name:'王五',score:80},
];
var first = _.first(stu,2);
console.log(first);

在上述代码中,通过first()函数返回stu数组对象中前两项的元素内容,并将它输出到浏览器的控制台中。


2.last()函数

调用格式:

_.last(array,[n])

该函数的功能是:返回数组的最后一个元素。如果设置了可选项n值,将返回一个包含后n项元素的新数组。示例如下。

var stu = [
	{name:'张三',score:60},
	{name:'李四',score:40},
	{name:'王五',score:80},
];
var last = _.last(stu,2);//如果第二个参数大于数组长度,也只显示3个。
console.log(last);

在上述代码中,通过last()函数返回stu数组对象中后两项的元素内容,并将它输出到浏览器的控制台中。


2.3.2 indexOf()和lastIndexOf()函数

在Underscore中,如果要查找某个元素是否存在于数组中,可以使用indexOf()和lastIndexOf()这两个函数。前者是查找元素首次出现的位置,后者是查找元素最后一次出现的位置,如果不存在,都返回-1,否则返回被查找元素在数组中的位置,即元素的索引号,该索引号从0开始。接下来分别对这两个函数进行介绍。


1.indexOf()函数

调用格式:

_.indexOf(array,value,[isSorted])

该函数的功能是:返回value值在数组array中首次出现的位置。如果存在,返回value值在数组array中的索引号;如果不存在,则返回-1值。在一个较大的数组array中,如果该数组已经排序过,可以使用可选参数isSorted,该参数用于加速查找的过程。示例如下。

var stu = ['张三','李四','王五'];
var find = _.indexOf(stu,'李四');
console.log(find);

上述代码通过indexOf()函数在数组stu中查找“李四”元素,并将查找结果显示在浏览器的控制台中。由于元素“李四”包含在数组stu中,因此将在控制台输出被查找元素在数组首次出现的位置,即索引号为1。

注意:indexOf()函数是全字匹配,数组中的元素内容必须与查找字符value完全一样才能算是存在,否则都将返回-1,表示没有找到。


2.lastIndexOf()函数

调用格式:

_.lastIndexOf(array,value,[fromIndex])

该函数的功能是:返回value值在数组array中最后一次出现的位置。如果存在,返回value值在数组array中的索引号;如果不存在,则返回-1值。可选项fromIndex表示指定查找的最大索引号位置。示例如下。

var stu = ['李四','王二','李四','张三','李四'];
var find = _.lastIndexOf(stu,'李四',3);
console.log(find);

在上述代码中,数组stu包含3个不同索引号位置而内容都为“李四”的元素。当使用lastIndexOf函数在最大索引号为3的范围内查找“李四”这个元素时(在索引号小于3的范围里找),该元素最后一次出现的索引号位置则为2,最后将该值输出至浏览器的控制台中。


2.3.3 without()和union()函数

在Underscore中,如果要排除数组中的某些元素或将多个数组进行拼接,可以使用without()或union()函数。前者是一个排他函数,可以移除数组中指定的某些元素,返回一个新的数组;后者则可以将多个元素进行连接,除掉重复元素项,同样也返回一个新的数组。接下来,分别对这两个函数的使用方法进行详细介绍。


1.without()函数

调用格式:

_.without(array,[*values])

该函数的功能是:返回一个不包含可选项values元素的新数组,参数array为原数组,可选项*values为原数组中的各个元素。示例如下。

var newarr = _.without([40,60,50,40,4],4,40);
console.log(newarr);


在上述代码中,without()函数返回的新数组不包含4和40两个元素。在执行该函数时,将在原数组的基础之上,返回一个不包含4和40两个元素的新数组newarr,并将该数组输出到浏览器的控制台中。


2.union()函数

调用格式:

_.union(*arrays)

该函数的功能是:返回组合后的数组列表。参数arrays是一个或多个数组列表。如果多个数组中有重复的元素,在返回的组合数组列表中仅显示一次。示例如下。

var newarr = _.union([1,2,3],[3,4,5],[5,6,7]);
console.log(newarr);

在上述代码中,union()函数将3个数组进行合并重组,各数组中相同元素项仅保留一次,因此,在浏览器控制台输出的数组元素为“1,2,3,4,5,6,7”。


2.4函数

2.4.1 delay()函数

在Underscore库中,delay()函数的功能类似于JavaScript中的setTimeout()方法,即表示推迟一段代码或一个函数的执行。它的调用格式如下。

_.delay(function,wait,[*arguments])

其中,参数function为自定义的函数,wait为设置延迟的时间(单位为毫秒),可选参数arguments为调用自定义函数时所需的实参(如果函数有参数)。示例如下。

var fun = function(n){
	console.log("你输入的是:"+n);
}
_.delay(fun,2000,"哈哈哈哈");

在上述代码中,先定义一个函数fun,该函数的功能是在控制台中输出用户输入的任意字符内容。然后调用delay()函数,在延时2000毫秒后,执行fun函数,在执行时,将实参“哈哈哈哈”传入形参n。最后浏览器的控制台输出如上图所示。


2.4.2 once()函数

在Underscore库中,执行once()函数类似于对变量进行打包初始化的过程。once()函数仅执行一次,再次执行时就无效了,因为,once()函数常用于对项目变量进行初始化赋值。

其调用格式如下。

_.once(function)

其中,参数function是一个函数的名称,执行once()函数时,将调用名称为function的函数。再次执行once()函数时,将不再调用该函数,仅执行一次。示例如下。

var num;
var str;
var fun = function(){
	num = 0;
	str = "1";
	console.log("初始化成功!");
}
var init = _.once(fun);//返回值是一个函数
//_.once(fun); //这个并不是调用的意思   .once(fun)()这个才表示调用
init();//这个才表示调用
console.log("初始化后值->num:"+num+";str:"+str);

在上述代码中,先定义两个变量num和str,然后自定义一个函数fun。在该函数中,对已定义的两个变量进行初始化赋值,赋值完成后在控制台输出“初始化成功!”的字样。

最后将once()函数调用时的返回值(一个函数)保存在init变量中。由于该返回值是一个函数,当调用该函数时,将执行自定义函数fun的初始化功能,在初始化完成后,再将两个变量num和str的值显示在浏览器的控制台中。

2.4.3 wrap()函数

在Underscore库中,wrap()函数的作用是包装,包装方式是把函数本身包装至wrapper(包装外层)中。在调用时,函数本身仅作为wrapper(包装外层)的一个参数进行传入。

具体调用格式如下。

_.wrap(function,wrapper)

其中,参数function是被包装的函数,wrapper是包装外层,它也是一个函数,但这个函数的参数就是被包装的函数本身(第一个参数)。示例如下。

var input = function(n,s){
	return s?n+",先生":n+",女士";
}
input = _.wrap(input,function(input){
	return "你好,"+input("皮卡丘",1)+",欢迎来到Backbone世界!";
});
console.log(input());

在上述代码中,先自定义一个iuput函数,该函数有两个参数n和s,前者用于传递用户输出的“姓名”字符内容,后者用于传递“性别”。当“性别”为非0时,表示“男”,便在返回的“姓名”字符内容后添加“先生”字样,否则表示“女”,将在返回的“姓名”字符内容后添加“女士”字样。

接下来,调用wrap()函数对自定义的input函数进行包装。在包装时,input函数作为wrapper(包装外层)函数的一个参数进行数据传递,并在input函数前后添加了其他字符串内容,通过return语句一起返回给调用函数。


2.4.4 compose()函数
在Underscore库中,compose()函数的功能是返回一个经过多个函数组合后的列表,用于计算在数学中一些比较复杂的运算,其调用格式如下。

_.compose(*functions)

其中,参数*functions表示多个参数,compose()函数可以将这些函数以一种有序的包含方式进行组合,例如参数*function中依次包含A、B两个函数。当执行compose()函数时,过程是这样的:先调用B函数,再将它的返回值作为A函数的参数,即A(B())。如果依次包含A、B、C三个函数,则执行过程是:A(B(C ())),依此类推。示例如下。

var A = function(a1){
	return a1*a1;
}
var B = function(b1){
	return b1*b1;
}
var C = function(c1){
	return c1*c1;
}
var D = _.compose(A,B,C);
console.log("最终结果为:"+D(2));
在上述代码中,先自定义3个函数,分别是A、B、C,它们的功能都是计算输入参数的平方,然后调用compose()函数将上述的3个函数按照包含的方式进行组合,并将组合后返回的结果赋予函数D。最后使用输入值2调用函数D,并将返回的结果显示在浏览器的控制台中。

从上图中可以看出,当使用输入值2调用函数D时,其最终的结果为256,该值的计算过程为:2*2=4,4*4=16,16*16=256,即按照A(B(C()))顺序进行执行。


2.5对象

2.5.1 keys()和values()函数

在Underscore库中,有许多对象的组成格式为key/value方式,针对这种现象,如果需要获取它的全部key值名称或value值,可以通过调用keys()和values()函数,前者返回一个包含全部key值名称的数组,后者返回一个包含全部value值的数组,下面逐一进行介绍。


1.keys()函数

调用格式:

_.keys(object)

该函数的功能是:检索并返回对象的属性名称,返回格式为数组。参数object表示任意一个组成格式为key/value的对象。示例如下。

var info = {
	name:'皮卡丘',
	sex:'男',
	email:'111@qq.com'
}
var arrkey = _.keys(info);
console.log(arrkey);

在上述代码中,先自定义一个名称为info的对象,包含3个key属性name、sex、email;然后将info对象作为参数执行keys函数,并将返回的数组保存至变量arrkey中;最后将该变量在浏览器的控制台中输出。


2.valuse()函数

调用格式:

_.values(object)

该函数的功能是:返回对象的属性值,返回格式为数组。其中参数object表示任意一个组成格式为key/value的对象。示例如下。

var info = {
	name:'皮卡丘',
	sex:'男',
	email:'111@qq.com'
}
var arrvalue = _.values(info);
console.log(arrvalue);

在上述代码中,调用valuse()函数将获取对象的属性值保存至变量arrvalue中,最后将该变量在浏览器的控制台中输出。


2.5.2 pick()和omit()函数

在Underscore库中,如果要挑选和排除对象中的任意key属性,可以使用pick()和omit()函数,前者可以从指定的对象中挑选出需要的任意key属性,后者能够从指定的对象中排除不需要的任意key属性,两者都返回一个新的对象。接下来分别进行介绍。


1.pick()函数

调用格式:

_.pick(object,*keys)

该函数的功能是:返回一个只有列入挑选key属性的对象。其中,参数object为JSON格式的对象,*keys表示多个需要挑选出来的key属性。示例如下。

var data = {
	A:1,
	B:2,
	C:3,
	D:4,
}
var newdata = _.pick(data,'B','C');
console.log(newdata);

在上述代码中,先定义一个名为data的对象,该对象中包含4个属性,分别为A、B、C、D;然后调用pick()函数,挑选key的属性为B、C,并将返回的对象赋予newdata;最后,在控制台输出该对象的内容


2.omit()函数

调用格式:

_.omit(object,*keys)
该函数的功能是:返回一个没有列入排除key属性的对象。其中,参数object为JSON格式的对象,*keys表示多个需要排除掉的key属性。示例如下。

var data = {
	A:1,
	B:2,
	C:3,
	D:4,
}
var newdata = _.omit(data,'B','C');
console.log(newdata);

在上述代码中,调用omit()函数,排除key的属性为B、C,将返回的对象赋予变量newdata,并在控制台输出该对象的内容。


2.5.3 defaults()函数

在Underscore库中,可以通过defaults()函数设置对象的默认属性值,如果这些默认的属性被重置,则使用defaults()函数设置的属性值无效,以重置后的值为准。其调用格式如下。

.defaults(object,*defaults)

该函数的功能是:返回一个设置了默认属性内容的对象。其中,参数object为设置默认属性的对象,*defaults为需要设置的默认属性列表。示例如下。

var info = {};
info = _.defaults(info,{
	name:'',
	email:'111@qq.com'
});
info.name = "皮卡丘";
console.log(info);

在上述代码中,先定义一个名为info的空对象,然后调用defaults()函数为空对象设置默认属性内容。完成设置后,再重置info对象的“name”属性值,最后在浏览器的控制台中输出整个info对象的内容。


2.5.4 has()函数

在Underscore库中,has()是一个很实用的函数,它可以检测出JSON格式的对象中,是否存在某个属性(key)值。如果存在,返回true,否则返回false。has()函数常用于调用对象的某属性之前的检测,通过该功能可以避免调用对象空属性的错误,它的调用格式如下。

_.has(object,key)

该函数的功能是:检测对象中是否包含给定的属性(key),结果返回true或false。其中,参数object为对象,key表示对象中包含的属性名称。示例如下。

var info = {
	name:'皮卡丘',
	sex:'男',
	email:'111@qq.com'
}
var strShow;
if(_.has(info,'score')){
	strShow = info.score;
}else{
	strShow = "对象中不包含该属性!";
}
console.log(strShow);

在上述代码中,先自定义一个名为info的JSON格式对象和一个用于输出的字符串变量“strShow”,然后调用has()函数检测对象中是否包含score属性。如果存在,将该属性值赋予变量“strShow”,否则将错误提示信息赋予变量。最后,在浏览器控制台中输出该变量的内容。

从上图可以看出,由于info对象中不存在名称为“score”的属性,因此在浏览器的控制台中输出错误提示信息。如果不使用has()函数进行属性检测,而直接访问对象的属性,将出现“undefined”异常。


2.6功能

2.6.1 random()函数

在Underscore库中,random()函数的功能是获取指定数字范围内的随机数。与传统的JavaScript获取随机数代码相比较,random()函数更简单。该函数的默认最小范围数字为0,该值可以省略,只设置一个最大范围值,此时将返回一个从0到这个最大范围值的随机数。

其调用格式如下。

._random(min,max)

该函数的功能是:返回一个在最小值和最大值之间的随机数。其中,参数min、max分别表示生成随机数的最小和最大范围数值。最小范围数值可以省略,如果省略,表示它的最小范围值为0.示例如下。

var intdef = _.random(10);
var intnum = _.random(10,20);
console.log("两个随机数分别为:"+intdef+","+intnum);

上述代码中,先定义两个变量intdef和intnum,前者用于保存只设置最大范围值是10的随机数,后者用于保存10~20间的随机数;然后,将获取的这两个变量,通过浏览器的控制台进行输出。


注意:

在random()函数中,当指定的范围值为10~20,也包含这两个范围本身,即函数也将返回10或20。

2.6.2 escape()和unescape()函数

esacpe()和unescape()是一对编码和解码函数,escape()函数功能是对指定的字符串内容进行解码,该函数返回一个编码后的新字符串;而unescape()函数则是对编码后的新字符串进行解码,解码后的字符串为escape()函数编码前的原始字符内容。接下来逐一进行介绍。


1.escape()函数

调用格式:

_.escape(string)

该函数的功能是:返回一串编码后的新字符串内容。参数string为编码前的字符串。

在使用escape()函数进行编码时,被编码的字符串的字符有的被替换成了十六进制的转义序列,有的则被替换成一些常用的HTML代码。


2.unescape()函数

调用格式:

_.unescape(string)

该函数的功能是:将编码后的字符串进行解码,返回字符串编码前的原始内容。参数string为已编码的字符串。示例如下。

var stresc = _.escape("111/163'haha'<hehe>&gaga-_.!~*")
var strunesc = _.unescape(stresc);
console.log("编码后:"+stresc);
console.log("编码前:"+strunesc);

在上述代码中,使用escape()函数对一串特殊的字符串内容进行编码,并将编码后的新字符串内容赋值给变量“stresc”;然后对已编码字符串调用unescape()函数进行解码,并将解码后的原始字符串内容复制给变量“strunesc”;最后,通过浏览器的控制台输出这两个变量的值。

从上图中可以看出,escape()函数在编码时不会对ASCII字母数字以及“-_.!~*”等特殊的字符进行编码,它们只是原样输出,除此之外的字符将被转移字符所替代。


2.6.3 template()函数

在Underscore库中,template()是一个十分重要的函数,这个轻量级的函数可以帮助开发人员有效地组织页面的结构和底层逻辑。该函数可以解析3种模板标签,分别如下表所示。

template()函数模板标签
模板标签功能描述
<% %>标签中包含的通常是JavaScript代码,在页面渲染数据时被执行
<%= %>标签中包含的通常是变量名、函数名、对象属性,执行时直接展现调用后的数据
<%- %>标签在输出数据时,能将HTML标记转成常用字符串形式,以免代码的攻击


template()函数的调用格式如下。

_.template(templateString,[data],[settings])

其中参数templateString就是模板标签,可选参数data为渲染标签的数据,可选参数settings为自定义模板标签的字符格式,比如可以将<% %>修改为{% %}格式,接下来通过简单的事例逐一进行介绍。

1.<% %>模板标签

<% %>在template()函数使用时,在它包含处可以执行任意的JavaScript代码,同时允许在调用template()函数时使用对象属性的方式传递参数值。示例如下。
var tpl = _.template("<%console.log(str)%>");
tpl({str:'姓名:皮卡丘'});
在上述代码中,首先使用<% %>模板标签调用template()函数。在标签中,将通过控制台输出指定的任意字符,然后执行tpl函数,执行时使用对象属性的方式向标签中的形参变量赋值。最终在Chrome浏览器的控制台输出。

2.<%= %>模板标签
与<% %>模板标签不同,<%= %>模板标签可以直接显示变量或函数的结果。它的功能是输出数据,而不是执行。因此,如果想使用<%= %>模板标签实现与上图同样的效果,代码修改如下。
var tpl = _.template("<%=str%>");
console.log(tpl({str:'姓名:皮卡丘'}));
上述代码中的tpl函数可以显示传入的任意字符内容,当在控制台输出该函数时候,其实效果和上图一样。


3.<%- %>模板标签
<%- %>与<%= %>模板标签的功能基本相同,不同之处在于,<%- %>模板标签不仅可以输出变量或函数的结果,而且可以将结果中的HTML代码转成字符形式,以避免代码受到攻击。如果希望只返回字符串,使用<%- %>模板标签是一个不错的选择。示例如下。
var tpl = _.template("<%-str%>");
console.log(tpl({str:"姓/'名'&:<皮>卡丘"}));
在上述代码的输出结果中,添加一些任意的HTML格式代码,而当使用<%- %>模板标签输出这些内容时,其中的HTML代码会转成转义符。它的转换标准与前面介绍的escape()函数一样,只是针对部分HTML代码进行替换,并不是全部。最终在Chrome浏览器的控制台输出效果如上。


示例2-1  <script>模板标签的使用

与上述三种模板标签都不相同,<script>模板标签是在HTML页面中进行声明的,声明的标志是将该标签的type属性值设置为“text/template”,即表示这是一个模板标签。在模板标签中,还可以添加<% %>和<%= %>标签来组织和布局页面的结构,然后调用template()函数,通过ID号绑定<script>模板标签,并将可选参数data的内容渲染到模板标签中对应的对象属性中,从而实现根据模板绑定数据的页面效果。接下来通过一个示例进行详细介绍。

1.功能描述
在页面中,首先使用<script>标签的方式自定义模板;然后创建一个数据源,调用template()函数解析模板,并将数据源填充至模板中并返回填充后的模版内容;最后将填充后的模板内容追加到页面的渲染元素内,从而最终实现根据自定义模板展示数据的功能。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>template自定义模板</title>
<script src="../script/jquery-1.11.1.js"></script>
<script src="../script/underscore.js"></script>
<script src="../script/backbone.js"></script>
<style type="text/css">
   body{ font-size:13px;}
   ul{ list-style-type:none;
      padding:0px;margin:0px;width:360px }
   li:first-child span{ float:left;
      border-bottom:solid 1px #ccc;background-color:#eee; 
      font-weight:bold }
   ul li span{ width:80px;text-align:left;float:left; 
      padding:0px 5px;border-bottom:dashed 1px #ccc;line-height:28px;}
</style>
</head>
<body>
	<!--这段script是段模板代码 ,接收数据后并生成HTML代码 -->
	<script type="text/template" id="tpl">
		<%
			var intSumScore=0;
			var intAveScore=0;
			for(var i=0;i<list.length;i++){
				var item = list[i]
		%>
		<li>
			<span>
				<%=item.StuId%>
			</span>
			<span>
				<%=item.Name%>
			</span>
			<span>
				<%=item.Sex%>
			</span>
			<span>
				<%=item.Score%>
			</span>
		</li>
		<%
				intSumScore+=parseInt(item.Score);	
				intAveScore=intSumScore/list.length;	
			}
		%>
		<li>
			<span>平均分:</span>
			<span><%=intAveScore%></span>
			<span>总分:</span>
			<span><%=intSumScore%></span>
		</li>
	</script>
	<!-- 将上面模板代码生成的HTML代码添加到这段代码后面 -->
	<ul id="element">
		<li>	
			<span>学号</span>
			<span>姓名</span>
			<span>性别</span>
			<span>总分</span>
		</li>
	</ul>
	<script type="text/javascript">
		var ele = $("#element");
		var tpl = $("#tpl").html();
		var data = {
	        list: [
	            { StuId: 's0101', Name: '刘小明', Sex: '男', Score: '345' },
	            { StuId: 's0102', Name: '李清燕', Sex: '女', Score: '445' },
	            { StuId: 's0103', Name: '张二保', Sex: '男', Score: '355' },
	            { StuId: 's0104', Name: '陈明基', Sex: '男', Score: '564' },
	            { StuId: 's0105', Name: '舒明珠', Sex: '女', Score: '543' }
	        ]
	    };
		var html = _.template(tpl,data);
		ele.append(html);
	</script>
</body>
</html>
2.源码分析
HTML页面代码由三部分组成:第一部分是<script>元素的模板标签,第二部分是页面中用于渲染填充数据的元素,第三部分是编写JavaScript代码:创建数据、绑定模板、渲染数据。接下来我们逐一介绍。
(1)在<script>元素的模板标签中,分别使用<% %>、<%= %>标签来执行代码和显示数据,在执行代码时,先定义了两个变量,用于保存数据中的总分数和平均分数值,然后使用for语句遍历填充数据的数组对象list。在遍历过程中,使用<%= %>标签直接显示对象中的各项元素,同时计算总分数和平均分数值,最后将获取的这两项数值使用<%= %>标签的方式直接显示在<span>元素中。
(2)在页面渲染元素ID为“element”的<ul>元素中,先添加一个<li>元素,用于填充数据的标题部分,全部的填充数据通过追加的方式添加至该元素中。
(3)在页面的JavaScript代码部分,首先定义两个变量ele和tpl,分别用于保存页面的渲染元素和模板内容;然后创建一个数据对象data,这个对象也可以通过请求服务端的数据接口进行返回;调用template()函数解析模板,并将创建的数据对象填充至模板中,同时,执行该函数后,返回一个数据填充至模版后的内容;最后,通过append()方法将该内容追加到页面的渲染元素中,最终实现通过template()函数绑定并显示的页面效果。


2.6.4 chin()函数

在Underscore库中,有一个作用与jQuery中链式写法相似的函数,它就是chain(),调用该函数后,可以在代码中采用链式写法,逐层获取返回值。其调用格式如下。

_.chain(obj)

该函数的功能是:返回一个包装后的对象,当再次调用该对象的方式时,将继续返回该对象的另外属性值,即可以逐层返回一个对象的多个属性值。参数obj可以是一个数组、集合、对象。示例如下。

var data = [1,2,3,4,5,6,7,8,9,10];
var find = _.chain(data)
			.filter(function(num){
				return num%2==0;
			})
			.without(data,2,10)
			.last()
			.value();
console.log("最终值为:"+find);


在上述代码中,先定义一个变量data,用于保存数组对象;然后调用chain()函数包装这个数组对象;最后采用链式写法,根据每次的返回结果一次调用filter()、without()、last()、value()函数,而调用时各个对象的返回结果又不相同。接下来进行逐步分析。

1.当调用filter()函数时候,返回一个可以被2整除的数组对象,也就是原始data数组中的偶数部分,即[2,4,6,8,10]。

2.当调用without()函数时,将在返回的偶数数组中,返回一个元素值除2和10之外的数组,即[4,6,8]。

3.当调用last()函数时,将返回最新数组对象中的最后一个元素项,即[8]。

4.当调用value()函数时,将直接返回数组的元素值,即8。

因此,当通过console.log方法在控制台输出变量find内容时,其显示内容为8。


注意:

在上述代码中value()也是一个很实用的函数,它的功能是获取包装对象的值,其调用格式如下:

_(obj).value()

在上述调用格式代码中,参数obj可以是任意的对象,包括集合、数组等。


Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
项目描述:建立购物小商城平台. 实现了前台页面系统。 技术描述:通过Spring 主框架来管理Struts2和Hibernate 框架搭建的电商小平台,用MySQL数据库并创建了表有用户表,订单表,商品表,商品分类表,商品内容表,购物车表等来存储数据。用到hibernate….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值