YUI Array 之each| forEach(遍历)
1. yui-each原码:
遍历YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) { Native.forEach.call(array || [], fn, thisObj || Y); return Y; } : function (array, fn, thisObj) { for (var i = 0, len = (array && array.length) || 0; i < len; ++i) { if (i in array) { fn.call(thisObj || Y, array[i], i, array); } } return Y; //返回Y,便于链式操作 };
2.tangram-each
tangram遍历var T,baidu=T= function(){ ///import baidu; baidu.each = function( enumerable, iterator, context ) { var i, n, t, result; if ( typeof iterator == "function" && enumerable) { // Array or ArrayLike or NodeList or String or ArrayBuffer n = typeof enumerable.length == "number" ? enumerable.length : enumerable.byteLength; if ( typeof n == "number" ) { // 20121030 function.length //safari5.1.7 can not use typeof to check nodeList - linlingyu if (Object.prototype.toString.call(enumerable) === "[object Function]") { return enumerable; } for ( i=0; i<n; i++ ) { //enumerable[ i ] 有可能会是0 t = enumerable[ i ]; t === undefined && (t = enumerable.charAt && enumerable.charAt( i )); // 被循环执行的函数,默认会传入三个参数(i, array[i], array) result = iterator.call( context || t, i, t, enumerable ); // 被循环执行的函数的返回值若为 false 和"break"时可以影响each方法的流程 if ( result === false || result == "break" ) {break;} } // enumerable is number } else if (typeof enumerable == "number") { for (i=0; i<enumerable; i++) { result = iterator.call( context || i, i, i, i); if ( result === false || result == "break" ) { break;} } // enumerable is json } else if (typeof enumerable == "object") { for (i in enumerable) { if ( enumerable.hasOwnProperty(i) ) { result = iterator.call( context || enumerable[ i ], i, enumerable[ i ], enumerable ); if ( result === false || result == "break" ) { break;} } } } } return enumerable; }; return baidu; }();
3.tangram-array each原码
tangram array遍历var T,baidu=T= function(){ ///import baidu.type; ///import baidu.array; ///import baidu.each; ///import baidu.forEach; baidu.array.extend({ each: function(iterator, context){ return baidu.each(this, iterator, context); }, forEach: function(iterator, context){ return baidu.forEach(this, iterator, context); } }); /// Tangram 1.x Code Start // TODO: delete in tangram 3.0 baidu.array.each = baidu.array.forEach = function(array, iterator, context) { var fn = function(index, item, array){ return iterator.call(context || array, item, index, array); }; return baidu.isEnumerable(array) ? baidu.each(array, typeof iterator == "function" ? fn : "", context) : array; }; /// Tangram 1.x Code End return baidu; }();
4.underscore each 原码:
underscore array遍历var each = _.each = _.forEach = function(obj, iterator, context) { if (obj == null) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === +obj.length) { for (var i = 0, l = obj.length; i < l; i++) { if (iterator.call(context, obj[i], i, obj) === breaker) return; } } else { for (var key in obj) { if (_.has(obj, key)) { if (iterator.call(context, obj[key], key, obj) === breaker) return; } } } };
5. qwrap – each
qwrap array遍历forEach: function(arr, callback, pThis) { for (var i = 0, len = arr.length; i < len; i++) { if (i in arr) { callback.call(pThis, arr[i], i, arr); } } }
比较
a. YUI会调用原生的forEach,可以用来遍历array,string,不能遍历object,也不会打断遍历
b.tangram最严谨,排除了function具有length属性,但YUI与underscore用了in 这个来排除掉了function,可以返回break 或者false打断遍历,可以用来遍历对象
c. underscore 会调用原生的forEach,可以用来遍历对象,数组,字符串,可以被打断遍历,这个函数在underscore是一个基础的函数,
d. qwrap的最简洁,不会调用原生forEach,也不能打断遍历