ES6中forEach方法

来源:互联网 发布:上海证券手机交易软件 编辑:程序博客网 时间:2024/06/02 06:47

forEach

forEach是Array新方法中最基本的一个,就是遍历,循环。例如下面这个例子:

?
1
[1, 2 ,3, 4].forEach(alert);

等同于下面这个传统的for循环:

?
1
2
3
4
5
var array = [1, 2, 3, 4];
 
for(var k = 0, length = array.length; k < length; k++) {
  alert(array[k]);
}

Array在ES5新增的方法中,参数都是function类型,默认有传参,这些参数分别是?见下面:

?
1
2
3
4
5
6
7
8
9
[1, 2 ,3, 4].forEach(console.log);
 
// 结果:
 
// 1, 0, [1, 2, 3, 4]
// 2, 1, [1, 2, 3, 4]
// 3, 2, [1, 2, 3, 4]
// 4, 3, [1, 2, 3, 4]
<span style="font-family: Arial, Verdana, sans-serif;">显而易见,forEach方法中的function回调支持3个参数,第1个是遍历的数组内容;第2个是对应的数组索引,第3个是数组本身。</span>

因此,我们有:

?
1
2
3
[].forEach(function(value,index, array) {
    // ...
});

对比jQuery中的$.each方法:

?
1
2
3
$.each([],function(index, value, array) {
    // ...
});

会发现,第1个和第2个参数正好是相反的,大家要注意了,不要记错了。后面类似的方法,例如$.map也是如此。

现在,我们就可以使用forEach卖弄一个稍显完整的例子了,数组求和:

?
1
2
3
4
5
6
7
8
varsum= 0;
 
[1, 2, 3, 4].forEach(function(item, index, array) {
  console.log(array[index] == item); // true
  sum+= item;
});
 
alert(sum); // 10

再下面,更进一步,forEach除了接受一个必须的回调函数参数,还可以接受一个可选的上下文参数(改变回调函数里面的this指向)(第2个参数)。

?
1
array.forEach(callback,[ thisObject])

例子更能说明一切:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
vardatabase= {
  users: ["张含韵","江一燕","李小璐"],
  sendEmail:function(user) {
    if (this.isValidUser(user)) {
      console.log("你好,"+ user);
    }else{
      console.log("抱歉,"+user+",你不是本家人"); 
    }
  },
  isValidUser:function(user) {
    return/^张/.test(user);
  }
};
 
// 给每个人法邮件
database.users.forEach(  // database.users中人遍历
  database.sendEmail,    // 发送邮件
  database              // 使用database代替上面标红的this
);
 
// 结果:
// 你好,张含韵
// 抱歉,江一燕,你不是本家人
// 抱歉,李小璐,你不是本家
如果这第2个可选参数不指定,则使用全局对象代替(在浏览器是为window),严格模式下甚至是undefined.

另外,forEach不会遍历纯粹“占着官位吃空饷”的元素的,例如下面这个例子:
?
1
2
3
4
5
6
7
8
var array = [1, 2, 3];
 
deletearray[1]; // 移除 2
alert(array); // "1,,3"
 
alert(array.length); // but the length isstill 3
 
array.forEach(alert); // 弹出的仅仅是1和3

综上全部规则,我们就可以对IE6-IE8进行仿真扩展了,如下代码:

?
1
2
3
4
5
6
7
8
9
10
11
// 对于古董浏览器,如IE6-IE8
 
if (typeof Array.prototype.forEach != "function") {
  Array.prototype.forEach = function(fn, context) {
    for(var k = 0, length = this.length; k < length; k++) {
      if (typeof fn === "function"&& Object.prototype.hasOwnProperty.call(this, k)) {
        fn.call(context, this[k], k, this);
      }
    }
  };
}
原创粉丝点击