jQuery Utilities就是一些实用函数,定义在jQuery对象中。它们大多数都比较简单,但因为通用所以在源代码的许多地方都有用到,正因为如此,其它某 些语言内置就提供这些功能,如果熟悉这些语言,则不需要看源代码也能够清楚其功能。不像其它函数,这部分要介绍的函数都比较独立,可以单独介绍。
(1)jQuery.each
这个函数可能是用得最多的一个,它用于对数组或对象进行遍历。下面是它的源代码实现:
第 3个参数args仅在内部使用(我搜索整个jQuery源代码也没有看到在哪里有用),通过它可以传递额外的参数,这里略去不讲,也就是代码的第 674-683行。第686行判断object不是数组(或类数组),即一个普通对象。第687-689行使用for...in循环对它的所有属性遍历, 对每个函数调用callback回调函数,它接受两个参数,一个是属性名,一个是属性名对应的值,也就是object[属性名],它也是this对象。另 外如果回调函数如果返回false,则中断遍历。第686-694则是对数组进行遍历,回调函数也接受两个参数,第一个为索引,第二个数组中该索引处的 值,this也是这个对象。同样地,当回调函数返回false时,中断循环。each函数最终返回object,即要遍历的对象或数组。另外jQuery 对象也有一个each方法(即jQuery.fn.each),由于它只传递一个callback参数,它对当前jQuery对象进行遍历。
(2)jQuery.map
它用于将一个数组通过某种规则转变成另一个数组,例如要将一个数组的所有的元素变成大写,可以调用:
其源代码实现很简单:
它 就是对数组的每个元素进行遍历,将对它们调用callback函数,将其返回值添加到ret中,第1158行用于辗平数组,如果在1158行之前ret为 [['a', 'b'], ['c', 'd']],那么经过1158行的调用后,ret的值为['a', 'b', 'c', 'd'],这个行为可能和别的语言中的map行为不同。
(3) jQuery.extend
jQuery.extend有许多不 同的变种,最完整的版本为jQuery.extend(deep, target, object1, ..., objectN),它将object1, ..., objectN中的所有属性拷贝到target中相应属性中。其中第一个参数表示是否为深拷贝,这个参数可选,默认是浅拷贝;第二个参数是拷贝的目的对 象,这个参数也是可选,默认为this;最后的所有参数为拷贝源。这个函数是这样判断有没有提供target参数,它先判断第一个参数是不是 boolean类型,如果是表示它是deep参数,先抛开它。剩下的参数如果只有一个参数,则表示没有target,使用默认值,否则使用target就 是剩下的第一个参数,其它参数就是拷贝源。
jQuery的Utitlies函数就讲这些,其它的一些还有如grep(对数组元素进行过滤),makeArray(将任意对象转变成数组),inArray(在数组中搜索对象返回其索引),merge(将两个数组元素合并),unique(去掉数组中重复元素)等,它们的实现也并不复杂。
(1)jQuery.each
这个函数可能是用得最多的一个,它用于对数组或对象进行遍历。下面是它的源代码实现:
670 // args is for internal usage only
671 each: function( object, callback, args ) {
672 var name, i = 0, length = object.length;
673
674 if ( args ) {
675 if ( length === undefined ) {
676 for ( name in object )
677 if ( callback.apply( object[ name ], args ) === false )
678 break;
679 } else
680 for ( ; i < length; )
681 if ( callback.apply( object[ i++ ], args ) === false )
682 break;
683
684 // A special, fast, case for the most common use of each
685 } else {
686 if ( length === undefined ) {
687 for ( name in object )
688 if ( callback.call( object[ name ], name, object[ name ] ) === false )
689 break;
690 } else
691 for ( var value = object[0];
692 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
693 }
694
695 return object;
696 },
第 3个参数args仅在内部使用(我搜索整个jQuery源代码也没有看到在哪里有用),通过它可以传递额外的参数,这里略去不讲,也就是代码的第 674-683行。第686行判断object不是数组(或类数组),即一个普通对象。第687-689行使用for...in循环对它的所有属性遍历, 对每个函数调用callback回调函数,它接受两个参数,一个是属性名,一个是属性名对应的值,也就是object[属性名],它也是this对象。另 外如果回调函数如果返回false,则中断遍历。第686-694则是对数组进行遍历,回调函数也接受两个参数,第一个为索引,第二个数组中该索引处的 值,this也是这个对象。同样地,当回调函数返回false时,中断循环。each函数最终返回object,即要遍历的对象或数组。另外jQuery 对象也有一个each方法(即jQuery.fn.each),由于它只传递一个callback参数,它对当前jQuery对象进行遍历。
(2)jQuery.map
它用于将一个数组通过某种规则转变成另一个数组,例如要将一个数组的所有的元素变成大写,可以调用:
var upperArr = jQuery.map(arr, function(n, i) { return n.toUpperCase(); })
其源代码实现很简单:
1146 map: function( elems, callback ) {
1147 var ret = [];
1148
1149 // Go through the array, translating each of the items to their
1150 // new value (or values).
1151 for ( var i = 0, length = elems.length; i < length; i++ ) {
1152 var value = callback( elems[ i ], i );
1153
1154 if ( value != null )
1155 ret[ ret.length ] = value;
1156 }
1157
1158 return ret.concat.apply( [], ret );
1159 }
它 就是对数组的每个元素进行遍历,将对它们调用callback函数,将其返回值添加到ret中,第1158行用于辗平数组,如果在1158行之前ret为 [['a', 'b'], ['c', 'd']],那么经过1158行的调用后,ret的值为['a', 'b', 'c', 'd'],这个行为可能和别的语言中的map行为不同。
(3) jQuery.extend
jQuery.extend有许多不 同的变种,最完整的版本为jQuery.extend(deep, target, object1, ..., objectN),它将object1, ..., objectN中的所有属性拷贝到target中相应属性中。其中第一个参数表示是否为深拷贝,这个参数可选,默认是浅拷贝;第二个参数是拷贝的目的对 象,这个参数也是可选,默认为this;最后的所有参数为拷贝源。这个函数是这样判断有没有提供target参数,它先判断第一个参数是不是 boolean类型,如果是表示它是deep参数,先抛开它。剩下的参数如果只有一个参数,则表示没有target,使用默认值,否则使用target就 是剩下的第一个参数,其它参数就是拷贝源。
562 jQuery.extend = jQuery.fn.extend = function() {
563 // copy reference to target object
564 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
565
566 // Handle a deep copy situation
567 if ( typeof target === "boolean" ) {
568 deep = target;
569 target = arguments[1] || {};
570 // skip the boolean and the target
571 i = 2;
572 }
573
574 // Handle case when target is a string or something (possible in deep copy)
575 if ( typeof target !== "object" && !jQuery.isFunction(target) )
576 target = {};
577
578 // extend jQuery itself if only one argument is passed
579 if ( length == i ) {
580 target = this;
581 --i;
582 }
583
584 for ( ; i < length; i++ )
585 // Only deal with non-null/undefined values
586 if ( (options = arguments[ i ]) != null )
587 // Extend the base object
588 for ( var name in options ) {
589 var src = target[ name ], copy = options[ name ];
590
591 // Prevent never-ending loop
592 if ( target === copy )
593 continue;
594
595 // Recurse if we're merging object values
596 if ( deep && copy && typeof copy === "object" && !copy.nodeType )
597 target[ name ] = jQuery.extend( deep,
598 // Never move original objects, clone them
599 src || ( copy.length != null ? [ ] : { } )
600 , copy );
601
602 // Don't bring in undefined values
603 else if ( copy !== undefined )
604 target[ name ] = copy;
605
606 }
607
608 // Return the modified object
609 return target;
610 };
jQuery的Utitlies函数就讲这些,其它的一些还有如grep(对数组元素进行过滤),makeArray(将任意对象转变成数组),inArray(在数组中搜索对象返回其索引),merge(将两个数组元素合并),unique(去掉数组中重复元素)等,它们的实现也并不复杂。
0 评论:
发表评论