Problem
You want to create a generic function, that produces for a given function the partial applied function.
Ingredients
- 2 functions
 - the 
apply()method - the 
slice()method 
Directions
- 
Define a function that accepts another function (the one that should be partial applicable).
function partial(fn /*, args...*/) { ... } 
- 
Let the function return another function (this will be the partial applicable function).
function partial(fn /*, args...*/) { ... return function() { ... } } - 
Convert all but the first argument to an array by borrowing the
slice()method.function partial(fn /*, args...*/) { var args = Array.prototype.slice.call(arguments, 1); return function() { ... }; } - 
Convert the arguments of the inner function to an array.
function partial(fn /*, args...*/) { var args = Array.prototype.slice.call(arguments, 1); return function() { var argsInner = Array.prototype.slice.call(arguments, 0); ... }; } - 
Combine the arguments of the outer function with the arguments of the inner function.
function partial(fn /*, args...*/) { var args = Array.prototype.slice.call(arguments, 1); return function() { var argsInner = Array.prototype.slice.call(arguments, 0); var argsAll = args.concat(argsInner); ... }; } - 
Call the passed function using the
apply()method, passing the combined arguments.function partial(fn /*, args...*/) { var args = Array.prototype.slice.call(arguments, 1); return function() { var argsInner = Array.prototype.slice.call(arguments, 0); var argsAll = args.concat(argsInner); return fn.apply(this, argsAll); }; } - 
Optional: combine the previous three steps.
function partial(fn /*, args...*/) { var args = Array.prototype.slice.call(arguments, 1); return function() { return fn.apply(this, args.concat(Array.prototype.slice.call(arguments, 0))); }; } - 
Voilá, a perfect, tasteful generic function that creates partial applicable functions.
function partial(fn /*, args...*/) { var args = Array.prototype.slice.call(arguments, 1); return function() { return fn.apply(this, args.concat(Array.prototype.slice.call(arguments, 0))); }; } function createPerson(firstName, lastName) { return { firstName: firstName, lastName: lastName } } var createPersonWithFirstNameJohn = partial(createPerson, 'John'); var johnDoe = createPersonWithFirstNameJohn('Doe'); console.log(johnDoe.firstName); // "John" console.log(johnDoe.lastName); // "Doe" 
Alternative recipes
- Since ES2015: use rest parameters, fat arrow functions and the spread operator (implementation will follow in a later blog post).