最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin3浏览0评论

Why does the reverse2 function using _.map() work, but the arr.map() doesn't work in this situation? Is there a syntax problem? I haven't been able to figure it out.

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]

Why does the reverse2 function using _.map() work, but the arr.map() doesn't work in this situation? Is there a syntax problem? I haven't been able to figure it out.

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]
Share Improve this question asked Aug 18, 2015 at 16:52 jmancherjejmancherje 6,6438 gold badges38 silver badges59 bronze badges 3
  • 2 Never ever modify an array while iterating it. Or expect anything to work like that. – Bergi Commented Aug 18, 2015 at 17:15
  • The native map method jumps over holes. So don't delete elements from it. – Bergi Commented Aug 18, 2015 at 17:18
  • looks like _.map doesn't dupe the array before passing it to the callback, like the OEM does. it has a few other non-conformities as well, but they allow a much faster operation than the native. – dandavis Commented Aug 18, 2015 at 17:31
Add a ment  | 

2 Answers 2

Reset to default 5

Array.prototype.map

This is tricky question. To explain why Array.prototype.map behaves this way we need to check specification. So:

  1. Let O be the result of calling ToObject passing the this value as the argument.
  2. Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length".
  3. Let len be ToUint32(lenValue).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  6. Let A be a new array created as if by the expression new Array(len) where Array is the standard built-in constructor with that name and len is the value of len. ...

The important points here to pay attention are #2 and #6. From them it's obvious that map creates a new array with the same length as the original one.

Then another thing from the same section about method:

... 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.

And it gives the answer to your question: map will create an array of the same length but since in iteration function you are removing elements from original array (with pop), new array populated with only second half of the original.

_.map

Why Underscore _.map function behave differently? Because the implementation of it iterates over all items of the original array. Hence the difference.

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.
发布评论

评论列表(0)

  1. 暂无评论