Created
April 3, 2011 04:00
-
-
Save kbjr/900164 to your computer and use it in GitHub Desktop.
A convenient way of stacking up functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
|------------------------------------------------ | |
| CallStack | |
|------------------------------------------------ | |
| | |
| A convenient way of stacking up functions | |
| | |
| @author James Brumond | |
| @copyright Copyright 2011 James Brumond | |
| @license Dual licensed under MIT and GPL | |
| | |
*/ | |
// ---------------------------------------------------------------------------- | |
// The actual code; see below for some samples | |
window.CallStack = (function() { | |
var arrayFunctions = [ | |
'pop', 'push', 'reverse', 'shift', 'slice', 'splice', 'unshift', 'concat' | |
]; | |
return function() { | |
var | |
stack = [ ], | |
retLast = false, | |
// Build the function | |
func = function() { | |
var argv = Array.prototype.slice.call(arguments, 0), ret = [ ]; | |
for (var i = 0, c = stack.length; i < c; i++) { | |
ret.push(stack[i].apply(this, argv)); | |
} | |
if (retLast) { | |
return ret.pop(); | |
} else { | |
return ret; | |
} | |
}; | |
// Extend the CallStack object with the stack array's prototype | |
for (var i = 0, c = arrayFunctions.length; i < c; i++) { | |
if (typeof Array.prototype[arrayFunctions[i]] === 'function') { | |
func[arrayFunctions[i]] = (function(j) { | |
if (j === 'concat') { | |
return function() { | |
var argv = Array.prototype.slice.call(arguments, 0); | |
for (var k = 0, c2 = argv.length; k < c2; k++) { | |
if (argv[k].onlyReturnLast && argv[k].getStack) { | |
argv[k] = argv[k].getStack(); | |
} | |
} | |
return stack[j].apply(stack, argv); | |
} | |
} else { | |
return function() { | |
return stack[j].apply(stack, Array.prototype.slice.call(arguments, 0)); | |
}; | |
} | |
}(arrayFunctions[i])); | |
} | |
} | |
// Hide the function contents | |
func.toString = function() { | |
return '[function CallStack]'; | |
}; | |
// Allow the developer to override the return functionality | |
func.onlyReturnLast = function(flag) { | |
retLast =!! flag; | |
}; | |
// Gets the actual call stack array | |
func.getStack = function() { | |
return stack; | |
}; | |
return func; | |
}; | |
}()); | |
// ---------------------------------------------------------------------------- | |
// Examples :) | |
// Create a new CallStack object | |
var myCallback = CallStack(); // Note: no "new" keyword | |
// The CallStack object contains all the basic | |
// array functions, including push(). | |
myCallback.push(function(a, b, c) { | |
return a + b + c; | |
}); | |
// When the stack is given more than one funciton, | |
// they are called in sequence. | |
myCallback.push(function(a, b, c) { | |
return [a, b, c]; | |
}); | |
// And you call it just like any other function... | |
myCallback(1, 2, 3); | |
// | |
// Which returns: | |
// | |
// [ | |
// 0: 6, // The result of the first function | |
// 1: [1, 2, 3] // The result of the second function | |
// ] | |
// | |
// ---------------------------------------------------------------------------- | |
// A slightly more useful example (as an event function) | |
// Create an element to bind our event to | |
var myLink = document.createElement('a'); | |
// Add an onclick event using CallStack | |
myLink.onclick = CallStack(); | |
// Make only the last return value get returned | |
myLink.onclick.onlyReturnLast(true); | |
// Add a function | |
myLink.onclick.push(function(e) { | |
var e = e || window.event; | |
// This return will be ignore because it isn't last | |
return true; | |
}); | |
// Add another one | |
myLink.onclick.push(function() { | |
// This will actually get returned because it's the last one | |
return false; | |
}); | |
/* End of file callstack.js */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment