欢迎访问我的github:huanshen,有我的源码解析
1、each
跟for循环很像,但是更有用,如果你理解了就知道了。
// 遍历一个数组或者对象 // obj 是需要遍历的数组或者对象 // callback 是处理数组/对象的每个元素的回调函数,它的返回值实际会中断循环的过程 // args 是额外的参数数组 each: function( obj, callback, args ) { var value, i = 0, length = obj.length, isArray = isArraylike( obj ); //如果args存在的话,callback中传入的参数是grgs,each循环次数确是由obj来确定的 if ( args ) { if ( isArray ) { for ( ; i < length; i++ ) { value = callback.apply( obj[ i ], args ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.apply( obj[ i ], args ); if ( value === false ) { break; } } } // A special, fast, case for the most common use of each //注意下面用的是call,上面是apply //apply 的第二个参数以数组的形式传入,但是真正运行的时候, //传入的数组参数会变成一个个的形式,而不是一个数组参数 } else { if ( isArray ) { for ( ; i < length; i++ ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } } return obj; },
2.makeArray
将类数组对象转化为数组。中间用到了merge函数,具体可见第三个函数,有说明。
// 将类数组对象转换为数组对象 // 此方法为内部方法 makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { // 如果 arr 是一个类数组对象,调用 merge 合到返回值 //还是不是很理解isArraylike和merge if ( isArraylike( Object(arr) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { // 如果不是数组,则将其放到返回数组末尾 // 等同于 ret.push(arr); core_push.call( ret, arr ); } } return ret; },
关于中间的Object()可以看看下面的结果(暂时不是很清楚具体的作用):
var str="tttt", arr1=[1,2,3], obj={1:0}, str2=Object(str); console.log( Object(str))//{0: "t", 1: "t", 2: "t", 3: "t", length: 4, [[PrimitiveValue]]: "tttt"} console.log(str2.length)//4 console.log(Object(arr1))//[1, 2, 3] console.log(Object(obj))//{1: 0}
3、merge
可以合并两个数组或者类数组对象
//把second中的属性添加到first中 //second可以是数组或者类数组对象,又或者包含0,1属性的东西 merge: function( first, second ) { var l = second.length, i = first.length, j = 0; if ( typeof l === "number" ) { for ( ; j < l; j++ ) { first[ i++ ] = second[ j ]; } } else { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; } } first.length = i; return first; },
4、map
功能跟each差不多,但是也有不一样的地方,主要是在处理第三个参数方面。
map: function( elems, callback, arg ) { var value, i = 0, length = elems.length, isArray = isArraylike( elems ), ret = []; // Go through the array, translating each of the items to their //如果是数组,isArray=true; //与each传入参数顺序是一致的 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 ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } } // Flatten any nested arrays return core_concat.apply( [], ret ); },
5、proxy
proxy(),接受一个函数,然后返回一个新函数,并且这个新函数始终保持了特定的上下文(context )语境。
proxy: function( fn, context ) { var tmp, args, proxy; if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. if ( !jQuery.isFunction( fn ) ) { return undefined; } // Simulated bind //如果传入的参数多余2个,把多余的参数转变为数组。 args = core_slice.call( arguments, 2 ); proxy = function() { //这里用到了柯里化 return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; },
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。具体可以看下面这个示例:可以看到前面两个参数并没有输出,最后一个参数和新的参数组成数组输出。在上面就是作为参数传入proxy中
function t (l,t,y){ var args = [].slice.call( arguments, 2 ); console.log(args) function t(){ console.log(args.concat([].slice.call( arguments ))); } return t; } var tt=t(1,2,3); tt("t");//[3,"t"]
时间: 2024-10-18 14:26:09