Skip to content

Commit

Permalink
Merge pull request jashkenas#1689 from akre54/partial-placeholder
Browse files Browse the repository at this point in the history
add support for changing _.partial's placeholder
  • Loading branch information
jridgewell committed Apr 3, 2015
2 parents 483fc0f + e848714 commit 90a95ec
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
12 changes: 11 additions & 1 deletion test/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@
ok(widget instanceof MyWidget, 'Can partially bind a constructor');
equal(widget.get(), 'foo', 'keeps prototype');
deepEqual(widget.options, {a: 1});

_.partial.placeholder = obj;
func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
equal(func('a'), 4, 'allows the placeholder to be swapped out');

_.partial.placeholder = {};
func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
equal(func('a'), 5, 'swapping the placeholder preserves previously bound arguments');

_.partial.placeholder = _;
});

test('bindAll', function() {
Expand Down Expand Up @@ -575,7 +585,7 @@
deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4));
deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11));
});

});

}());
10 changes: 7 additions & 3 deletions underscore.js
Original file line number Diff line number Diff line change
Expand Up @@ -697,21 +697,25 @@

// Partially apply a function by creating a version that has had some of its
// arguments pre-filled, without changing its dynamic `this` context. _ acts
// as a placeholder, allowing any combination of arguments to be pre-filled.
// as a placeholder by default, allowing any combination of arguments to be
// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
_.partial = function(func) {
var boundArgs = slice.call(arguments, 1);
var boundArgs = slice.call(arguments, 1),
placeholder = _.partial.placeholder;
var bound = function() {
var position = 0, length = boundArgs.length;
var args = Array(length);
for (var i = 0; i < length; i++) {
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
}
while (position < arguments.length) args.push(arguments[position++]);
return executeBound(func, bound, this, this, args);
};
return bound;
};

_.partial.placeholder = _;

// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
Expand Down

0 comments on commit 90a95ec

Please sign in to comment.