Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created July 2, 2012 20:41
Show Gist options
  • Save cowboy/3035578 to your computer and use it in GitHub Desktop.
Save cowboy/3035578 to your computer and use it in GitHub Desktop.
JavaScript: practical partial application, like creating a function that can be passed to Array#filter or the like.
/*
* Function#filterify
*
* Copyright (c) 2012 "Cowboy" Ben Alman
* Licensed under the MIT license.
* http://benalman.com/about/license/
*/
Function.prototype.filterify = (function() {
// IIFE gives us a place for storing local vars...
var arraySlice = Array.prototype.slice;
// ...and keeps the local "filterify" NFE name from leaking in IEs.
return function filterify() {
var fn = this;
// "Pre" arguments.
var pre = arraySlice.call(arguments);
// "Post" arguments.
var post = [];
// Search the arguments for placeholder.
var idx = pre.indexOf(filterify);
// If placeholder was found, adjust both pre and post so that they
// are the arguments before and after the placeholder.
if (idx !== -1) {
post = pre.splice(idx, pre.length - idx).slice(1);
}
// The returned function will be passed to Array#filter or the like and
// should only accept one argument.
return function filterified(value) {
// Invoke the original function, inserting the passed-in value wherever
// the "filterify" placeholder was (or at the end).
return fn.apply(this, pre.concat(value, post));
};
};
}());
var foo = function(a, b, c) {
console.log(a, b, c);
};
foo("a", "b", "c");
// a b c
console.log("---");
var __ = Function.filterify; // Placeholder reference
["_", "__", "___"].forEach(foo.filterify(__, "b", "c"));
// _ b c
// __ b c
// ___ b c
["_", "__", "___"].forEach(foo.filterify("a", __, "c"));
// a _ c
// a __ c
// a ___ c
["_", "__", "___"].forEach(foo.filterify("a", "b", __));
// a b _
// a b __
// a b ___
console.log("---");
["_", "__", "___"].forEach(foo.filterify());
// _ undefined undefined
// __ undefined undefined
// ___ undefined undefined
["_", "__", "___"].forEach(foo.filterify("a"));
// a _ undefined
// a __ undefined
// a ___ undefined
["_", "__", "___"].forEach(foo.filterify("a", "b"));
// a b _
// a b __
// a b ___
@cowboy
Copy link
Author

cowboy commented Jul 3, 2012

Good call. It's hard to keep track of method signatures when MDN also lists SpiderMonkey extensions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment