jQuery源码阅读5-2:字串数组工具2 Posted on 2014-05-16 | In jQuery源码阅读 | 剩这仨数组操作都稍微有点儿绕: 1:makeArray1234567891011121314151617181920212223core_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:grep123456789101112131415161718192021//过滤数组, 返回新副本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:map1234567891011121314151617181920212223242526272829303132333435363738394041424344/** * 博文作者: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 );},