使用JavaScript map()处理二维数组返回结果不符的原因
核心原因拆解
map的功能特性:map的作用是遍历原数组的每个元素,将回调函数的返回值收集起来,生成一个与原数组长度完全一致的新数组。你的原数组myArray包含3个子数组,所以newArray必然会有3个元素,这是得到二维数组的根本原因——你误解了map的用途,它不是用来生成单个结果数组,而是对每个元素做转换后生成同长度数组。this的引用一致性:map的第二个参数[]是一个固定的空数组,在整个遍历过程中,this始终指向这个数组的唯一引用。每次执行this.push(currentArray[3])都是往同一个数组里追加元素:第一次加4,第二次加2,第三次加5,最终这个数组变成[4,2,5]。返回同一引用导致的视觉重复:每次回调都返回
this,也就是这个唯一的数组引用。所以newArray的三个元素都是指向同一个数组的指针,当你打印newArray时,三个元素都会显示该数组最终的状态,看起来就是[[4,2,5], [4,2,5], [4,2,5]],但本质是三个引用指向同一个数组。console.log的输出误导:回调里的console.log("this: " + this)会自动将数组转为字符串,第一次输出this: 4,第二次this: 4,2,第三次this: 4,2,5,这让你误以为每次返回的是不同的数组,但实际上只是同一个数组在每次push后的内容变化,而你每次返回的都是它的引用。
正确写法
如果你想要得到[4,2,5],直接用map返回每个子数组的第四个元素即可:
let myArray = [ [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 5, 2, 4, 6, 1, 6], [9, 2, 4, 5, 1] ] let newArray = myArray.map(currentArray => currentArray[3]); console.log(newArray); // 输出 [4, 2, 5]
如果一定要用this的方式(不推荐,无必要),可以用forEach代替map,因为forEach仅做遍历执行,不会生成新数组:
let myArray = [ [1, 2, 3, 4, 5, 6, 7, 8], [8, 7, 5, 2, 4, 6, 1, 6], [9, 2, 4, 5, 1] ] let newArray = []; myArray.forEach(function(currentArray){ this.push(currentArray[3]); }, newArray); console.log(newArray); // 输出 [4, 2, 5]
内容的提问来源于stack exchange,提问作者Danny

