1 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解(转) 2 3 * ---------------------------------------------------------- 4 * 函数介绍 5 * 6 * each函数通过jQuery.extend函数附加到jQuery对象中: 7 * jQuery.extend({ 8 * each: function() {} 9 * }); 10 * 如果对jQuery.extend函数源码还不了解,可以参考《jQuery源码分析-extend函数》一文 11 * 12 * jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理 13 * jQuery.each方法可以为处理函数增加附带的参数(带参数与不带参数的回调使用方法不完全一致) 14 * 15 * ---------------------------------------------------------- 16 * 使用说明 17 * each函数根据参数的类型实现的效果不完全一致: 18 * 1、遍历对象(有附加参数) 19 * $.each(Object, function(p1, p2) { 20 * this; //这里的this指向每次遍历中Object的当前属性值 21 * p1; p2; //访问附加参数 22 * }, ['参数1', '参数2']); 23 * 24 * 2、遍历数组(有附件参数) 25 * $.each(Array, function(p1, p2){ 26 * this; //这里的this指向每次遍历中Array的当前元素 27 * p1; p2; //访问附加参数 28 * }, ['参数1', '参数2']); 29 * 30 * 3、遍历对象(没有附加参数) 31 * $.each(Object, function(name, value) { 32 * this; //this指向当前属性的值 33 * name; //name表示Object当前属性的名称 34 * value; //value表示Object当前属性的值 35 * }); 36 * 37 * 4、遍历数组(没有附加参数) 38 * $.each(Array, function(i, value) { 39 * this; //this指向当前元素 40 * i; //i表示Array当前下标 41 * value; //value表示Array当前元素 42 * }); 43 * ---------------------------------------------------------- 44 * 45 */ 46 //jQuery.each(), $.each() 47 //@param {Object}|{Array} object 需要遍历处理的对象或数组 48 //@param {Function} callback 遍历处理回调函数 49 //@param {Array} args callback回调函数的附加参数 50 each: function(object, callback, args){ 51 52 //当需要遍历的是一个对象时,name变量用于记录对象的属性名 53 var name, 54 55 //当需要遍历的是一个数组时,i变量用于记录循环的数组下标 56 i = 0, 57 58 //遍历数组长度,当需要遍历的对象是一个数组时存储数组长度 59 //如果需要遍历的是一个对象,则length === undefined 60 length = object.length, 61 62 //检查第1个参数object是否是一个对象 63 //根据object.length排除数组类型,根据isFunction排除函数类型(因为函数也是对象) 64 isObj = length === undefined || jQuery.isFunction(object); 65 66 //回调函数具有附加参数时,执行第一个分支 67 //if(!!args) { 68 if (args) { 69 70 //需要遍历的是一个对象 71 if (isObj) { 72 73 //遍历对象属性,name是对象的属性名,再函数顶部已声明 74 //许多人不太习惯for(var name in object)方式,如果不进行声明,则name就会被定义为全局变量 75 for (name in object) { 76 77 //调用callback回调函数,且回调函数的作用域表示为当前属性的值 78 //如:callback() { this; //函数中的this指向当前属性值 79 //将each的第3个参数args作为回调函数的附加参数 80 if (callback.apply(object[name], args) === false) { 81 82 //如果在callback回调函数中使用return false;则不执行下一次循环 83 break; 84 } 85 } 86 } 87 //需要遍历的是一个数组 88 else { 89 90 //循环长度,循环变量i在函数顶部已定义 91 //循环变量的自增在循环内部执行 92 for (; i < length;) { 93 94 //调用callback函数,与上面注释的callback调用一致 95 //此处callback函数中的this指向当前数组元素 96 if (callback.apply(object[i++], args) === false) { 97 break; 98 } 99 } 100 } 101 102 } 103 //回调函数没有附加参数时,执行第二个分支 104 else { 105 106 //需要遍历的是一个对象 107 if (isObj) { 108 109 //循环对象的属性名,name在函数顶部已定义 110 for (name in object) { 111 112 //调用callback回调函数 113 //在不带参数的对象遍历中,作用域表示为当前属性的值 114 //且回调函数包含两个参数,第一个数当前属性名,第二个是当前属性值 115 //我觉得这句代码修改一下会更好用:if(callback.call(object, name, object[name]) === false) { 116 if (callback.call(object[name], name, object[name]) === false) { 117 118 //如果在callback回调函数中使用return false;则不执行下一次循环 119 break; 120 } 121 } 122 } 123 //需要遍历的是一个数组 124 else { 125 //这里的for写法有点BT,解释为: 126 //var value = object[0]; 127 //for(; i < length;) { 128 // if(false === callback.call(value, i, value)) { 129 // break; 130 // } 131 // value = object[++i]; 132 //} 133 //同样,我觉得这里的代码稍加修改会更好用: 134 //for (; i < length && false !== callback.call(object, i, object[i++]);) { 135 //} 136 for (var value = object[0]; i < length && callback.call(value, i, value) !== false; value = object[++i]) { 137 } 138 } 139 } 140 141 //这里返回遍历的对象或数组,但object没有被更改,因此一般不给$.each()赋值 142 //但是如果按照我在注释中所修改的写法来使用,且在callback回调函数中对this(即对object的引用)进行了修改 143 //则这里返回的object是被修改后的对象或数组 144 return object; 145 }