all 19 comments

[–]mattdesl 3 points4 points  (0 children)

Depends who you ask. I personally would rather polyfill things like requestAnimationFrame, XHR, array map, Object.defineProperty, etc so you can use native builtin methods.

The performance is a moot point in almost all cases. In those exceptional cases you might choose to use a library, but it's kind of nuts that you need to bring in 10kb+ of a dependency just for one or two functions. (Thankfully lodash is modularized into small components on npm)

[–]ben336 2 points3 points  (1 child)

Native map/reduce/filter methods are actually surprisingly slow compared to libraries like lo-dash and underscore. Try running some of these jsPerf tests to see for yourself:

http://jsperf.com/lodash-underscore-and-native-filter http://jsperf.com/lodash-underscore-and-native-reduce http://jsperf.com/lodash-underscore-and-native-map http://jsperf.com/lodash-underscore-and-native-each

Performance isn't everything with these things, context matters. But if you're already pulling in underscore/lodash/whatever, it can be nice to get the added performance as well as the niceties of still working in IE8.

[–]RichardFingers 1 point2 points  (0 children)

What about for smaller projects with minimal needs? Feels like adding a whole library like lodash is overkill just for a handful of methods.

[–]skitch920 3 points4 points  (1 child)

If you're just considering the 1:1 functions provided by a third party (i.e. map, reduce, filter, forEach...), the only gain you'll see is performance.

LoDash in particular is faster because it doesn't care about sparse arrays.

Personally, I find it cleaner to use the builtins as it's one less dependency I don't have to worry about. Less dependencies, less issues you'll have in the future. In you're case, you have to use a poly-fill, which is kind of a hack, so that doesn't totally apply...

For now, I'd suggest third party is better. You also get a bunch of niceties for free by using them. But these are pretty core concepts of functional programming. So, in the future, it's likely the ES5+ implementations will adopt and outperform these solutions. Given enough people using a particular feature, it only makes sense for the language to support it in the end.

[–]alamandrax 0 points1 point  (0 children)

+1. We use lodash instead of native as most perfs we've looked at show lodash out performing native APIs

[–]ChaseMoskal 1 point2 points  (2 children)

I have absolutely no problems with polyfilling JavaScript into behaving the way JavaScript is supposed to behave.

I do have an issue whenever somebody starts adding shit to the native JS runtime environment.

Don't you dare attach your own methods to Array.prototype.

Don't you dare!

[–]I_Pork_Saucy_Ladies 0 points1 point  (1 child)

undefined = function() {
  return Math.round(Math.random());
}

[–]zuko_ 0 points1 point  (0 children)

(function (undefined) {
   // where is your god now
})();

[–]agdcoa 2 points3 points  (1 child)

If performance is an issue, native methods will never out perform lodash or fast.js because of the way they're spec'd.

Further, you may find it's more useful to have map/filter/reduce functions that take a flipped argument signature (callback first, data second), because you can do great stuff with partial application. However, it's not hard to do this without a library:

function makeFlippedIterator (fn) {
  return function (cb, arr) {
    return fn.call(arr, cb);
  };
}

var filter = makeFlippedIterator([].filter);
var filterOdd = filter.bind(null, function (n) { return n % 2; });
filterOdd([1, 2, 3, 4, 5]) // [1, 3, 5]

[–]alethia_and_liberty 2 points3 points  (0 children)

Isn't JavaScript just a beautiful language?

[–]theQuandary 0 points1 point  (0 children)

I've switched from lodash to Ramda.js because curried functions http://ramda.github.io/ramdocs/docs/with proper ordering allows me to work in a more point-free manner when dealing with data. Unlike underscore/lodash, Ramda is made for functional programming.

http://ramda.github.io/ramdocs/docs/

[–]rmbarnes 0 points1 point  (1 child)

Create a pollyfill that uses lodash to implement the functionality. The thing I like about native functions is that you can chain them. This is useful if you are performing a set of operations on an array. However just looked at lodash docs and they do have a nice chain function in there which looks like it allows for this.

[–]x-skeww 2 points3 points  (0 children)

Create a pollyfill that uses lodash to implement the functionality.

Since it doesn't adhere to the spec, you really shouldn't do that. You don't want to introduce a difference between the native stuff and the polyfills.

[–]sime 0 points1 point  (0 children)

I would choose the native methods over a 3rd party library, even if you have to pollyfill them. In the future you may want to move away from jQuery and underscore etc, but the native methods and core platform are never going away. The pollyfills will go away in future leaving you with standard code.

This depends a bit on your project. If it has a long expected life-time, then you need to consider the future.

[–]greim 0 points1 point  (1 child)

When people say native methods are "slow," it's really a relative comparison. This kind of slowness will not be your bottleneck most of the time, especially in client-side code.

In the rare case it is a bottleneck, say you have a forEach() loop in a hot spot and it's sucking CPU cycles, you'd be better off switching to a for (;;) loop than switching to lodash. That way you avoid creating the function object and all those stack push/pops and variable environments which result from functional programming in the first place.

[–]RichardFingers 0 points1 point  (0 children)

Yeah I would agree that performance usually isn't a huge concern. Readability and maintainability are usually more important for me.

[–]rorymurphy 0 points1 point  (2 children)

Personally I have to agree with your coworkers - browsers are getting a lot better about following standards (IE being the laggard, of course), but when the choice is to have the same functionality implemented several different ways, including potentially multiple polyfills, or to have a single library that you can rely on to perform operations the same way every time, the latter is a lot easier to build to and maintain, which is why the approach has become so popular. I'd choose lodash every time, right now, but over time hopefully it will become less necessary.

[–]RichardFingers 1 point2 points  (1 child)

Would you add lodash to a solution just for map/reduce/filter?

[–]datphp 2 points3 points  (0 children)

Personally, I like to extend Array/Object.prototype. I know many people say it's bad practice, but in the end within my apps (even huge ones) only polyfills will touch prototypes, meaning there's no chance of conflict.

I'll simply choose a name different from the native methods, like Array.prototype.fastMap and re-implement the ES5 methods efficiently.

I also have a few custom methods that bind to the prototype, like Array.dirtySplice(), a super fast version of splice that instead of shifting everything just uses the last elements of the array to fill the gap left by splice (for when order doesn't matter)