Javascript _.map() 对比 array.map();为什么一个在这里工作而不是另一个?

Javascript _.map() vs array.map(); why does one work here and not the other?

为什么在这种情况下使用_.map() 的reverse2 函数有效,而arr.map() 无效?有语法问题吗?我还没弄明白。

function reverse2(arr){
  return _.map(arr, function(val,index, arr1){return arr1.pop();});
}

console.log(reverse2([1,2,3,4,5,6]));   // logs [6,5,4,3,2,1]


function reverse3(arr){
  return arr.map(function(val,index, arr1){return arr1.pop();});
}

console.log(reverse3([1,2,3,4,5,6]));   // logs [6,5,4,undefined, undefined, undefined]

Array.prototype.map

这是个棘手的问题。解释一下为什么Array.prototype.map behaves this way we need to check specification。所以:

  1. O 是调用 ToObject 传递 this 值作为参数的结果.
  2. lenValue 为调用 O 的 [[Get]] 内部方法的结果,参数为“长度".
  3. len 为 ToUint32(lenValue)。
  4. 如果 IsCallable(callbackfn) 是 false,抛出一个 TypeError 异常。
  5. 如果提供了 thisArg,则让 TthisArg;否则让 Tundefined.
  6. A 是一个新数组,就好像由表达式 new Array(len) 创建,其中 Array 是具有该名称的标准内置构造函数,lenlen 的值。 ...

这里要注意的重点是#2 和#6。从他们那里可以明显看出,map 创建了一个与原始数组具有 相同 长度的新数组。

然后同一部分关于方法的另一件事:

... If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time map visits them; elements that are deleted after the call to map begins and before being visited are not visited.

它给出了你的问题的答案:map 将创建一个相同长度的数组,但由于在迭代函数中你要从原始数组中删除元素(使用 pop),新数组只填充第二个原来的一半。

_.map

为什么 Underscore _.map 函数表现不同?因为它的实现迭代了原始数组的 all 项。因此差异。

array.map

first call: [1,2,3,4,5,6], position 0 hash value '1', so pop 6.
seconde call: [1,2,3,4,5], position 1 hash value '2', so pop 5.
third call: [1,2,3,4], position 2 hash value '3', so pop 4.
fourth call: [1,2,3], position 3 hash no value, so pop nothing.