From 13ae2d6a5da848bb331bc2f3de6b259065a9c35a Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Mon, 23 Jun 2014 11:37:52 -0400 Subject: [PATCH 1/2] Optimization for compose (breaking) --- underscore.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/underscore.js b/underscore.js index 78bd4ca1a..cbf11066c 100644 --- a/underscore.js +++ b/underscore.js @@ -806,13 +806,14 @@ // Returns a function that is the composition of a list of functions, each // consuming the return value of the function that follows. _.compose = function() { - var funcs = arguments; + var funcs = arguments, length = funcs.length; return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; + var idx = length - 1, + result = funcs[idx].apply(this, arguments); + while (idx--) { + result = funcs[idx].call(this, result); } - return args[0]; + return result; }; }; From bc965280e24d53a1a73a6b46e7a66b460e5bdc1b Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Mon, 23 Jun 2014 11:46:45 -0400 Subject: [PATCH 2/2] Compose test coverage --- test/functions.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/functions.js b/test/functions.js index fbbac407b..390f563d3 100644 --- a/test/functions.js +++ b/test/functions.js @@ -476,6 +476,22 @@ composed = _.compose(greet, exclaim); equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + + // f(g(h(x, y, z))) + function h(x, y, z) { + equal(arguments.length, 3, 'First function called with multiple args'); + return z * y; + }; + function g(x) { + equal(arguments.length, 1, 'Composed function is called with 1 argument'); + return x; + }; + function f(x) { + equal(arguments.length, 1, 'Composed function is called with 1 argument'); + return x * 2; + }; + composed = _.compose(f, g, h); + equal(composed(1, 2, 3), 12); }); test('after', function() {