Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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]
like image 256
jmancherje Avatar asked Aug 18 '15 16:08

jmancherje


People also ask

What is the difference between map and array in JavaScript?

Map has a built-in ‘has’ function too. Note: Compared to the array’s includes function, Object’s hasOwnProperty and Set/Map’s has functions seem to perform close to O (1) in different tests, clearly more efficient in terms of larger data sets. 4. Removing Duplicates

What is the use of map in JavaScript?

Definition and Usage. The map() method creates a new array with the results of calling a function for every array element. The map() method calls the provided function once for each element in an array, in order. Note: map() does not execute the function for array elements without values.

What is the difference between map () and return value in JavaScript?

Meanwhile, the map () method will also call a provided function on every element in the array. The difference is that map () utilizes return values and actually returns a new Array of the same size.

What is the difference between foreach and map in JavaScript?

Well, the forEach() method doesn’t actually return anything (undefined). It simply calls a provided function on each element in your array. This callback is allowed to mutate the calling array. Meanwhile, the map() method will also call a provided function on every element in the array.


2 Answers

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.

like image 184
dfsq Avatar answered Oct 25 '22 07:10

dfsq


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.
like image 45
neo Avatar answered Oct 25 '22 08:10

neo