JS的forEach和map方法的区别(推荐)

日期:2018年12月16日 阅读次数:2856 分类:javascript

一、前言

forEach()和map()两个方法都是ECMA5中Array引进的新方法,主要作用是对数组的每个元素执行一次提供的函数,但是它们之间还是有区别的。jQuery也有一个方法$.each(),长得和forEach()有点像,功能也类似。但是从本质上还是有很大的区别的,那么我们探探究竟。

二、forEach和map语法

2.1、语法:

//forEach
array.forEach(callback(currentValue, index, array){
    //do something
}, this)
//或者
array.forEach(callback(currentValue, index, array){
    //do something
})

//map:
var new_array = arr.map(callback[, thisArg])

//.each()(selector).each(function(index,element))  // 注意参数的顺序,和以上两个相反

callback: 为数组中每个元素执行的函数,该函数接收三个参数。参数一:当前数组中元素;参数二:索引; 参数三:当前数组。
this:可选,执行回调时,this的指向。

2.2、区别

2.2.1、forEach()返回值是undefined,不可以链式调用。

2.2.2、map()返回一个新数组,原数组不会改变。

2.2.3、没有办法终止或者跳出forEach()循环,除非抛出异常,所以想执行一个数组是否满足什么条件,返回布尔值,可以用一般的for循环实现,或者用Array.every()或者Array.some()。

2.2.4、$.each()方法规定为每个匹配元素规定运行的函数,可以返回 false 可用于及早停止循环。

 

三、一些栗子

3.1、 在使用forEach()时候,如果数组在迭代的时候被修改,则其他元素会被跳过。因为 forEach()不会在迭代之前创建数组的副本。

var words = ['one','two','three','four'];
words.forEach(function (word) {
    console.log(word);
    if (word === 'two') {
        words.shift();
    }
})

// one
// two
// four

(这中适合使用for循环,用索引控制遍历所有项)

var words = ['one','two','three','four'];
for (var i=0; i<words.length; i++) {
    console.log(words[i]);
    if (words[i] === 'two') {
        words.shift();
        i--        // 删除后把索引重新调整
    }
}

// one
// two
// three
// four 

3.2、反转字符串

var str = '12345';

// 先转成数组,然后使用数据的反转方法(reverse),再转回字符串
Array.prototype.map.call(str, function(x) {   //此时利用了call()方法
  return x;
}).reverse().join('');

// 更简单的方法
str.split("").reverse().join("");

3.3、一个笔试题。

["1", "2", "3"].map(parseInt);  //结果  [1, NaN, NaN]

如果想得到[1, 2, 3]应该这么做

function returnInt(element){
  return parseInt(element,10);
}

["1", "2", "3"].map(returnInt);

这主要是因为 parseInt()默认有两个参数,第二个参数是进制数。当parsrInt没有传入参数的时候,而map()中的回调函数时候,会给它传三个参数,第二个参数就是索引,明显不正确,所以返回NaN了。

3.4、 forEach无法用来改变数组的内容,应该用map

使用forEach改变数组内容,无法改变数组内容

var arr = [1,2,3]
var newArr = arr.forEach(function(n){  
   n = n+1      //无法改变数组对应的项
});
console.log('arr', arr)
console.log('newArr', newArr)

// arr (3) [1, 2, 3]
// newArr undefined

应该使用map返回修改后的新数组

var arr = [1,2,3]
var newArr = arr.map(function(n){  
   return n+1   // 用return 返回新数组,如不使用return返回则新数组的每项都默认为'undefined'
});
console.log('arr', arr)
console.log('newArr', newArr)

// arr (3) [1, 2, 3]
// newArr (3) [2, 3, 4]

 

四、兼容性

forEach()和map()是ECMA5新引入的,可能在标准的其他实现中不存在,在使用前可以要Ployfill一下。
具体网上很多吧,更多的是在ie9以下,如果你的项目无视这些,那么你可以不关心兼容问题。

文章标签: