1 var each = _.each = _.forEach = function(obj, iterator, context) {
2 if (obj == null) return;
3 //首先判断是否支持原生的forEach方法
4 if (nativeForEach && obj.forEach === nativeForEach) {
5 obj.forEach(iterator, context);
6 //判断是否是数组 +obj.length 是强制类型转换,转换成整形,相当于Number(obj.length)
7 } else if (obj.length === +obj.length) {
8 for (var i = 0, length = obj.length; i < length; i++) {
9 //到这里可能会有疑惑,操作返回的结果跟breaker(一个空的对象)比较,为什么呢?{}比较是内存地址的比较
10 //其实在some方法中, each(obj, function(value, index, list) {
11 // if (result || (result = iterator.call(context, value, index, list))) return breaker;
12 // });可以看到,很显然,这是underscore内部方便跳出循环的方法
13 if (iterator.call(context, obj[i], i, obj) === breaker) return;
14 }
15 } else {
16 //次方法以及过滤了过贴位notEnumrable属性的元素.e.g.toString,valueOf...
17 var keys = _.keys(obj);
18 for (var i = 0, length = keys.length; i < length; i++) {
19 if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
20 }
21 }
22 };