【理解Underscore和Lo-Dash】Collections _.each

_.each

遍历集合,对集合中的每个元素执行回调。

API

Lo-Dash

_.forEach(collection [, callback=identity, thisArg])

Aliases

each

Arguments

  1. collection (Array|Object|String): 要遍历的集合
  2. [callback=identity] (Function): 每次迭代中调用的函数
  3. [thisArg] (任意): 绑定到callbackthis
  4. callback接受三个参数: (value, index|key, collection)

Returns

(Array, Object, String): 返回collection.

Underscore

_.each(list, iterator, [context])

Aliases

forEach

Arguments

  1. list (Array|Object|String): 要遍历的集合
  2. iterator (Function): 每次迭代中调用的函数
  3. [context] (任意): 绑定到callbackthis
  4. iterator接受三个参数: (element|value, index|key, list)

Returns

(Array, Object, String): 返回undefined.

Note

  • Lo-Dash可以省略回调函数,而Underscore则必须传入
  • Lo-Dash可以通过在回调中返回false提前结束迭代
  • Lo-Dash会返回Collection从而允许链式操作,Underscore的返回值则是undefined

Example

Lo-Dash

1

2

3

4

5

6

7

8

_.forEach([1,2,3])

// => 返回[1,2,3]



_([1, 2, 3]).forEach(alert).join(',');

// => alert每个数字并返回'1,2,3'



_.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);

// => alert每个数字value(不保证按照定义的顺序执行)

Underscore

1

2

3

4

_.each([1, 2, 3], alert);

// => alert每个数字

_.each({one : 1, two : 2, three : 3}, alert);

// => alert每个数字value(不保证按照定义的顺序执行)

Source

Lo-Dash

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function forEach(collection, callback, thisArg) {

    var index = -1,

    length = collection ? collection.length : 0;



    callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg);

    if (typeof length == 'number') {

        while (++index < length) {

            if (callback(collection[index], index, collection) === false) {

                break;

            }

        }

    } else {

        forOwn(collection, callback);

    }

    return collection;

}

Underscore

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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;

        }

      }

    }

  };

Additional

  • obj.length === +obj.length

+obj: 将obj转换成10进制数,否则返回NaN。因此,上面的判断等价于obj.length && typeof obj.length == 'number'

  • if (iterator.call(context, obj[i], i, obj) === breaker) return;

breaker是预先定义的空对象({}),Underscore内部用于提前结束循环的标志,并没有对外公开。另外,因为对象的===比较的是对象地址,所以就算用户在自己的iterator中返回{},上述if仍然不成立

  • for in循环不会遍历non-enumerable属性,因此像ObjecttoString等就不会被迭代

你可能感兴趣的:(Collections)