日期:2014-05-16  浏览次数:20399 次

求解释,each(forEach)函数,实在看不懂
遍历数组或对象里所有成员的函数。
来源是underescore中的源码,给改成普通函数了

function each(obj, iterator, context) {
      if (obj == null) {
return;
}
      else if (obj.length === +obj.length) {
        for (var i = 0, l = obj.length; i < l; i++) {
          if (iterator.call(context, obj[i], i, obj) === {}) return;
        }
      } 
      else {
        for (var key in obj) {
          if (iterator.call(context, obj[key], key, obj) === {}) return;
        }
     }
};

var data1 = [4,5,6,7];
var data2 = {
 "a": 4,
 "b": 5,
 "c": 6
}; 
each(data1,function say(i)
{
    alert(i)
}) //依次alert 4 5 6 7
问题1:obj.length === +obj.length 的含义是判断这个obj参数到底是数组还是对象吧?
问题2:第三个参数context的含义,例子中没有第三个参数照样能输出结果
问题3:iterator.call(context, obj[i], i, obj)和iterator.call(context, obj[key], key, obj)
改为iterator.call(context, obj[i])和iterator.call(context, obj[key])不行吗? 貌似去掉没啥影响吧

------最佳解决方案--------------------
1: 判断length是不是number
2: iterator的执行环境,缺省在window执行
3: 就say()来说没影响,别的iterator或许需要i/key和obj引用做进一步处理,具体意图author才知道。

------其他解决方案--------------------
引用:
1: 判断length是不是number
2: iterator的执行环境,缺省在window执行
3: 就say()来说没影响,别的iterator或许需要i/key和obj引用做进一步处理,具体意图author才知道。

++
因为这个函数只支持对数组和对象的each

1:判断obj是否数组的一种变异方法,你改成else if (obj[0])也可以,
3:允许迭代器iterator接收三个参数,以最大化满足它处理事务时的需求:
  1:是数组时:元素的值,索引,原数组
  2:是对象时:键值,键名,原对象 
var data2 = {
 "a": 4,
 "b": 5,
 "c": 6
};
each(data2,function say(value,name,o){
  alert(name+"="+value);
});