jQuery源码阅读5-2:字串数组工具2

剩这仨数组操作都稍微有点儿绕:

1:makeArray

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
core_push = Array.prototype.push,
//生成新数组 , 肩负着把乱七八糟东西转成数组的任务
//results仅内部使用
makeArray: function( arr, results ) {
var type,
ret = results || [];//不考虑内部使用,ret初始化为[]
if ( arr != null ) {
//类数组也有length, 这里判断一下类型
type = jQuery.type( arr );
//满足下边判断的, 就说明不是数组 , 直接push到末尾完事儿
if ( arr.length == null || type === "string" || type === "function"
|| type === "regexp" || jQuery.isWindow( arr ) ) {
//这里ret判断不为数组, 所以只能Array.prototype.push.call, 否则没有原生push方法
core_push.call( ret, arr );//返回新长度
} else {
//是数组,用之前分析的merge合并,
jQuery.merge( ret, arr );
}
}
return ret;
},

2:grep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//过滤数组, 返回新副本
grep: function( elems, callback, inv ) {
var retVal,
ret = [],//返回的结果数组
i = 0,
length = elems.length;
inv = !!inv;//相当于Boolean(inv)
for ( ; i < length; i++ ) {
//Boolean( callback的返回值 )
retVal = !!callback( elems[ i ], i );
//inv和callback返回值相反的, 不传默认是false, 也就是真逻辑的
if ( inv !== retVal ) {
//加到结果数组
ret.push( elems[ i ] );
}
}
return ret;
},

3:map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* 博文作者:ruantao1989@gmail.com
* 引自博客:ruantao.duapp.com/blog
*/
//返回新数组, 此数组每个元素都经过callback(经过计算或过滤)
//arg是内部参数
map: function( elems, callback, arg ) {
var value, key,
ret = [],
i = 0,
length = elems.length,
//第二个表达式整理一下比较好读,
//length !== undefined
//&& typeof length === "number"
//&& ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems )
//两种情况1是jQuery实例, 2是确定为数组
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
//是数组的情况,要遍历数组下标
if ( isArray ) {
for ( ; i < length; i++ ) {
//遍历元素经过callback
value = callback( elems[ i ], i, arg );
//回调返回null或undefined就不加到副本里了
if ( value != null ) {
ret[ ret.length ] = value;
}
}
//jQuery实例的话,要遍历元素
} else {
for ( key in elems ) {
value = callback( elems[ key ], key, arg );
//回调返回null或undefined就不加到副本里了
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
//这句不太好理解,
//就是1:[](第一个参数)调用"Array实例.concat"(concat是原型方法), 2:传入ret作为参数, 3:并且需要apply把数组参数转成多个参数的形式
return ret.concat.apply( [], ret );
},