each _.each(list, iteratee, [context])
Alias: forEach 遍历 list 中的所有元素,按顺序用每个元素当做参数调用 iteratee 函数。如果传递了 context 参数,则把 iteratee 绑定到 context 对象上。每次调用 iteratee 都会传递三个参数:(element, index, list)
。如果 list 是个 JavaScript 对象,iteratee 的参数是 (value, key, list)
)。返回 list 以方便链式调用。
1 2 3 4 _.each ([1 , 2 , 3 ], alert); => alerts each number in turn... _.each ({one : 1 , two : 2 , three : 3 }, alert); => alerts each number value in turn..
注意:集合函数能在数组,对象,和类数组对象,比如 arguments
, NodeList
和类似的数据类型上正常工作。 但是它通过鸭子类型 工作,所以要避免传递带有一个数值类型 length
属性的对象。每个循环不能被破坏 - 打破, 使用 _.find * 代替,这也是很好的注意。*
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import optimizeCb from './_optimizeCb.js' ;import isArrayLike from './_isArrayLike.js' ;import keys from './keys.js' ;export default function each (obj, iteratee, context ) { iteratee = optimizeCb (iteratee, context); var i, length; if (isArrayLike (obj)) { for (i = 0 , length = obj.length ; i < length; i++) { iteratee (obj[i], i, obj); } } else { var _keys = keys (obj); for (i = 0 , length = _keys.length ; i < length; i++) { iteratee (obj[_keys[i]], _keys[i], obj); } } return obj; }
辅助函数 optimizeCb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 export default function optimizeCb (func, context, argCount ) { if (context === void 0 ) return func; switch (argCount == null ? 3 : argCount) { case 1 : return function (value ) { return func.call (context, value); }; case 3 : return function (value, index, collection ) { return func.call (context, value, index, collection); }; case 4 : return function (accumulator, value, index, collection ) { return func.call (context, accumulator, value, index, collection); }; } return function ( ) { return func.apply (context, arguments ); }; }
IsArrayLike _isArrayLike.js 1 2 3 4 5 import createSizePropertyCheck from './_createSizePropertyCheck.js' ;import getLength from './_getLength.js' ;export default createSizePropertyCheck (getLength);
_createSizePropertyCheck.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import { MAX_ARRAY_INDEX } from './_setup.js' ;export default function createSizePropertyCheck (getSizeProperty ) { return function (collection ) { var sizeProperty = getSizeProperty (collection); return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX ; } }
_getLength.js 1 2 3 4 import shallowProperty from './_shallowProperty.js' ;export default shallowProperty ('length' );
_shadowProperty.js 1 2 3 4 5 6 export default function shallowProperty (key ) { return function (obj ) { return obj == null ? void 0 : obj[key]; }; }
keys 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import isObject from './isObject.js' ;import { nativeKeys, hasEnumBug } from './_setup.js' ;import has from './_has.js' ;import collectNonEnumProps from './_collectNonEnumProps.js' ;export default function keys (obj ) { if (!isObject (obj)) return []; if (nativeKeys) return nativeKeys (obj); var keys = []; for (var key in obj) if (has (obj, key)) keys.push (key); if (hasEnumBug) collectNonEnumProps (obj, keys); return keys; }