Search code examples
javascriptlodashunderscore.js

Is there any difference between Underscore _.map and the JS built-in function?


Looked around but couldn't find this question. Is there any practical difference between Underscore (or Lodash) _.map and the map function that's built into JavaScript? Can I use them interchangeably?

ie: is

_.map(myArr, a => {
  // do stuff...
})

equal to

myArr.map(a => {
  // do stuff...
}

Solution

  • There are two major differences between Array.prototype.map and Underscore's (or Lodash's) free-standing map function.

    Firstly, map works on objects without a length property while Array.prototype.map does not:

    import { map } from 'underscore';
    
    const square = x => x * x;
    const obj = {a: 1, b: 2, c: 3};
    
    map(obj, square); // fine, [1, 4, 9]
    [].map.call(obj, square); // error
    

    Secondly, like all Underscore collection functions, map supports convenient iteratee shorthands that Array.prototype.map does not:

    map([[1, 2, 3], [4, 5], [6]], 'length'); // [3, 2, 1]
    
    const people = [
        {name: 'Joe', occupation: 'news presenter'},
        {name: 'Jane', occupation: 'firefighter'},
    ];
    
    map(people, 'occupation');
    // ['news presenter', 'firefighter']
    
    map(people, ['occupation', 2]);
    // ['w', 'r'] (third character of occupation)
    
    map(people, {name: Jane}); // [false, true]
    

    A more minor difference, which only applies to Underscore, is that map supports an optional third argument that lets you bind the callback to this argument:

    const sourceObject = {
        greet(name) {
            return this.greeting + name;
        },
        greeting: 'Hello ',
    };
    
    const bindObject = {
        greeting: 'Goodbye ',
    };
    
    const names = map(people, 'name');
    
    map(names, sourceObject.greet, sourceObject);
    // [ 'Hello Joe', 'Hello Jane' ]
    
    map(names, sourceObject.greet, bindObject);
    // [ 'Goodbye Joe', 'Goodbye Jane' ]
    

    You can generally safely replace Array.prototype.map by Underscore's map, but not the other way round.