1. Self-Define Functions:
var scareMe = function () {
alert("Boo!");
scareMe = function () {
alert("Double boo!");
};
};
// using the self-defining functionscareMe(); // Boo!
scareMe(); // Double boo!
// 1. adding a new property
scareMe.property = "properly";
// 2. assigning to a different name
var prank = scareMe;
// 3. using as a method
var spooky = {
boo: scareMe
};
// calling with a new name
prank(); // "Boo!"
prank(); // "Boo!"console.log(prank.property); // "properly"
// calling as a method
spooky.boo(); // "Boo!"
spooky.boo(); // "Boo!"console.log(spooky.boo.property); // "properly"
// using the self-defined functionscareMe(); // Double boo!
scareMe(); // Double boo!console.log(scareMe.property); // undefined
2. Function Properties—A Memoization Pattern
var myFunc = function () {
var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)),
result;
if (!myFunc.cache[cachekey]) {
result = {};
// ... expensive operation ...
myFunc.cache[cachekey] = result;
}
return myFunc.cache[cachekey];
};
// cache storage
myFunc.cache = {};
//another example (arguments.callee is not allowed in ES5)
var myFunc = function (param) {
var f = arguments.callee,
result;
if (!f.cache[param]) {
result = {};
// ... expensive operation ...
f.cache[param] = result;
}
return f.cache[param];
};
// cache storage
myFunc.cache = {};
3.Partial Application
// a curried add()
// accepts partial list of argumentsfunction add(x, y) {
var oldx = x, oldy = y;
if (typeof oldy === "undefined") { // partial
return function (newy) {
return oldx + newy;
};
}
// full applicationreturn x + y;
}
// test
typeof add(5); // "function"
add(3)(4); // 7
// create and store a new function
var add2000 = add(2000);
add2000(10); // 2010
2. another example
// a curried add
// accepts partial list of arguments
function add(x, y) {
if (typeof y === "undefined") { // partial
return function (y) {
return x + y;
};
}
// full application
return x + y;
}
3. general-purpose currying function:
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}
// about usage
// a normal function
function add(a, b, c, d, e) {
return a + b + c + d + e;
}
// works with any number of arguments
schonfinkelize(add, 1, 2, 3)(5, 5); // 16
// two-step currying
var addOne = schonfinkelize(add, 1);addOne(10, 10, 10, 10); // 41
var addSix = schonfinkelize(addOne, 2, 3);addSix(5, 5); // 16