This is a pretty subjective question, so I suppose I'll give a subjective answer:
There are basically three things at issue here: actual code efficiency, code legibility, and code style. The last one doesn't really matter IMO except insofar as it affects legibility and the consistency of your code base.
In terms of efficiency,
_.reduce
is more efficient than_.map
+_.reduce
, so you can drop that idea. Using_.map
creates a new array with the transformed values - there's no need for this.The
_.each
+ summation function approach may be marginally less efficient (you need to keep track of your running-total variable somewhere else) and to my mind it's less legible, because it takes the relevant code and moves it further from the loop where you're using it. You also don't get a nice clean return value for your operation - instead, you have a variable hanging out somewhere in the outer scope that you need to first create and then re-use.I don't think "memoization" makes much sense here. You might want to cache the return value for a given cart, and invalidate that on item changes, but that's not actually memoizing. Memoization makes sense when a) an easily-hashed input will always produce the same answer, and b) calculating that answer is expensive. In this case, calculating the sum is probably cheaper than hashing the input (your item list).
In terms of legibility, I tend strongly towards using the Underscore aliases that shadow the names of real JS 1.8 methods (the exception, for me, is
.any
vs..some
, because I find it so much more legible). In this case, that means.reduce
, not.inject
or.foldl
. That makes it easier for a JS dev to understand what's intended, and JS devs are who you care about.