From 24d5fbb5954972db7afde1d65c3115045cd1da01 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 1 May 2012 00:34:40 -0400 Subject: [PATCH] lodash: Add support for "lazy" bind. [jddalton] Former-commit-id: 472c0436f7de4e636dd878900119008bf39592fa --- lodash.js | 40 ++++++++++++++++++++++++++++++++++------ test/test.js | 23 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/lodash.js b/lodash.js index 6e367de6e..a8e08578c 100644 --- a/lodash.js +++ b/lodash.js @@ -1432,30 +1432,58 @@ /** * Creates a new function that, when called, invokes `func` with the `this` * binding of `thisArg` and prepends additional arguments to those passed to - * the bound function. + * the bound function. Lazy defined methods may be bound by passing the object + * they are bound to as `func` and the method name as `thisArg`. * * @static * @memberOf _ * @category Functions - * @param {Function} func The function to bind. - * @param @param {Mixed} [thisArg] The `this` binding of `func`. + * @param {Function|Object} func The function to bind or the object the method belongs to. + * @param @param {Mixed} [thisArg] The `this` binding of `func` or the method name. * @param {Mixed} [arg1, arg2, ...] Arguments to prepend to those passed to the bound function. * @returns {Function} Returns the new bound function. * @example * + * // basic bind * var func = function(greeting) { return greeting + ': ' + this.name; }; * func = _.bind(func, { 'name': 'moe' }, 'hi'); * func(); * // => 'hi: moe' + * + * // lazy bind + * var object = { + * 'name': 'moe', + * 'greet': function(greeting) { + * return greeting + ': ' + this.name; + * } + * }; + * + * var func = _.bind(object, 'greet', 'hi'); + * func(); + * // => 'hi: moe' + * + * object.greet = function(greeting) { + * return greeting + ' ' + this.name + '!'; + * }; + * + * func(); + * // => 'hi moe!' */ function bind(func, thisArg) { var args = slice.call(arguments, 2), - argsLength = args.length; + argsLength = args.length, + isFunc = toString.call(func) == funcClass; + // juggle arguments + if (!isFunc) { + var methodName = thisArg; + thisArg = func; + } return function() { - args.length = argsLength; push.apply(args, arguments); - return func.apply(thisArg, args); + var result = (isFunc ? func : thisArg[methodName]).apply(thisArg, args); + args.length = argsLength; + return result; }; } diff --git a/test/test.js b/test/test.js index 49636cc14..77ffa7a08 100644 --- a/test/test.js +++ b/test/test.js @@ -76,6 +76,29 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.bind'); + + (function() { + test('supports lazy bind', function() { + var object = { + 'name': 'moe', + 'greet': function(greeting) { + return greeting + ': ' + this.name; + } + }; + + var func = _.bind(object, 'greet', 'hi'); + equal(func(), 'hi: moe'); + + object.greet = function(greeting) { + return greeting + ' ' + this.name + '!'; + }; + equal(func(), 'hi moe!'); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.forEach'); (function() {