jquery.map()⽅法的使⽤详解
原型⽅法map跟each类似调⽤的是同名静态⽅法,只不过返回来的数据必须经过另⼀个原型⽅法pushStack⽅法处理之后才返回,源码如下:
map: function( callback ) {
return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},
本⽂主要就是分析静态map⽅法⾄于pushStack在下⼀篇随笔⾥⾯分析;
⾸先了解下map的使⽤(⼿册内容)
$.map将⼀个数组中的元素转换到另⼀个数组中。
作为参数的转换函数会为每个数组元素调⽤,⽽且会给这个转换函数传递⼀个表⽰被转换的元素作为参数。
转换函数可以返回转换后的值、null(删除数组中的项⽬)或⼀个包含值的数组,并扩展⾄原始数组中。
参数
arrayOrObject,callbackArray/Object,FunctionV1.6
arrayOrObject:数组或者对象。
为每个数组元素调⽤,⽽且会给这个转换函数传递⼀个表⽰被转换的元素作为参数。
函数可返回任何值。
另外,此函数可设置为⼀个字符串,当设置为字符串时,将视为“lambda-form”(缩写形式?),其中 a 代表数组元素。
如“a * a”代表“function(a){ return a * a; }”。
⽰例1:
//将原数组中每个元素加 4 转换为⼀个新数组。
//jQuery 代码:
$.map( [0,1,2], function(n){
return n + 4;
});
//结果:
[4, 5, 6]
⽰例2:
//原数组中⼤于 0 的元素加 1 ,否则删除。
//jQuery 代码:
$.map( [0,1,2], function(n){
return n > 0 ? n + 1 : null;
});
//结果:
[2, 3]
⽰例3:
//原数组中每个元素扩展为⼀个包含其本⾝和其值加 1 的数组,并转换为⼀个新数组
//jQuery 代码:
$.map( [0,1,2], function(n){
return [ n, n + 1 ];
});
/
/结果:
[0, 1, 1, 2, 2, 3]
可以看出map⽅法跟each⽅法类似通过循环每个对象或者数组的“项”执⾏回调函数来实现对数组或者对象的操作,但是这两个⽅法也有很多不同点
⽐如each()返回的是原来的数组,并不会新创建⼀个数组,⽽map则会创建新的数组,;each遍历是this指向当前数组或对象值,map则指向window,因为在源码中并不像each那样使⽤对象冒充;
例如:
var items = [1,2,3,4];
$.each(items, function() {
alert('this is ' + this);
});
var newItems = $.map(items, function(i) {
return i + 1;
});
// newItems is [2,3,4,5]
//使⽤each时,改变的还是原来的items数组,⽽使⽤map时,不改变items,只是新建⼀个新的数组。
var items = [0,1,2,3,4,5,6,7,8,9];
var itemsLessThanEqualFive = $.map(items, function(i) {
// removes all items > 5
if (i > 5)
return null;
return i;
});
/
/ itemsLessThanEqualFive = [0,1,2,3,4,5]
⾔归正传回到map源码
// arg is for internal usage only
map: function( elems, callback, arg ) {
var value, key, ret = [],
i = 0,
length = elems.length,
// jquery objects are treated as arrays
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; // Go through the array, translating each of the items to their
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
// Go through every key on the object,
} else {
for ( key in elems ) {
value = callback( elems[ key ], key, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
// Flatten any nested arrays
at.apply( [], ret );
},
⾸先还是声明⼏个变量为接下来的遍历做准备,其中jsArray变量⽤来简单区分对象和数组,这个布尔复合表达式⽐较长不过只要记住js运算符的有优先顺序就不难理解了,⾸先括号优先执⾏然后就是逻辑与》逻辑或》全等》赋值,然后就可以分析啦
⾸先圆括号⾥先计算然后结果加上 length !== undefined 、 typeof length === "number这两个必要条件最后的结果再跟elems instanceof jQuery进⾏逻辑或的
运算,简单的说就是isArray为真的情况有:
1、elems instanceof jQuery 为true 换⾔之就是jquery对象
2、length !== undefined && typeof length === "number" 和 length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems )这三个⾄少成⽴⼀个
可以拆分为3个⼩情况
length是存在并且是数字⽽且待遍历的数组或者类数组等length属性⼤于0 length-1存在这样就保证了是能遍历的,⽐如对于jquery对象 domList对象等length是存在并且是数字⽽且length属性等于0 如果是0也没关系就是不会遍历
length是存在并且是数字⽽且待遍历对象是纯数组
满⾜这些条件之后开始根据isArray的结果分开遍历,对于“数组”采⽤for循环,对于对象采⽤in循环
// Go through the array, translating each of the items to their
if ( isArray ) {
typeof array
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
是数组或者类数组的时候直接把循环的每⼀项的值和指针以及arg参数传⼊回调函数中执⾏,arg参数是此⽅法内部使⽤的参数,跟each以及⼀些其他jquery⽅法很相似,只要在执⾏回调函数时不返回null就把执⾏返回的结果添加到新数组中,对象操作亦是如此直接略过
// Flatten any nested arrays
at.apply( [], ret );
最后将结果集扁平化,为什么有这⼀步呢?因为map是可以扩展数组的在前⾯第3个⽰例就是如此:
$.map( [0,1,2], function(n){
return [ n, n + 1 ];
});
如果是这样使⽤的话得到的新数组是⼀个⼆维数组,所以必须降维
map⽅法简单分析完毕,能⼒有限错误之处望多多指正。
以上所述就是本⽂的全部内容了,希望⼤家能够喜欢。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论