Created
February 10, 2012 20:46
-
-
Save jehugaleahsa/1792725 to your computer and use it in GitHub Desktop.
Handle Optional Parameters with Default Values in JavaScript
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
function assignArguments(values, expression) { | |
// determine how many arguments are needed for each parameter | |
// grab all of the defaults, too | |
var needed = 1; | |
var argsNeeded = {}; | |
var defaults = {}; | |
var queue = [expression]; | |
for (var queueIndex = 0; queueIndex < queue.length; ++queueIndex) { | |
var node = queue[queueIndex]; | |
if (typeof node === 'string') { | |
// the node is a required parameter | |
argsNeeded[node] = needed; | |
++needed; | |
} else if (node instanceof Array) { | |
// the node is a list of parameters | |
for (var index = 0; index !== node.length; ++index) { | |
queue.push(node[index]); | |
} | |
} else { | |
// the node is a list of optional parameters with defaults | |
// make sure there isn't more than one parameter | |
var count = 0; | |
for (var key in node) { | |
if (node.hasOwnProperty(key)) { | |
if (count !== 0) { | |
throw new Error('A default parameter list had more than one value.'); | |
} | |
defaults[key] = node[key]; | |
queue.push(key); | |
++count; | |
} | |
} | |
} | |
} | |
// determine the order that the parameters appear | |
var parameters = []; | |
var stack = [expression]; | |
while (stack.length > 0) { | |
var node = stack.pop(); | |
if (typeof node === 'string') { | |
// the node is a required parameter | |
parameters.push(node); | |
} else if (node instanceof Array) { | |
// the node is a list of parameters | |
var index = node.length; | |
while (index !== 0) { | |
--index; | |
stack.push(node[index]); | |
} | |
} else { | |
// the node is an optional parameter with defaults | |
// we'll check for multiple parameters | |
var count = 0; | |
for (var key in node) { | |
if (node.hasOwnProperty(key)) { | |
if (count > 0) { | |
throw new Error('A default parameter list had more than one value.'); | |
} | |
stack.push(key); | |
++count; | |
} | |
} | |
} | |
} | |
var result = {}; | |
var valueIndex = 0; | |
for (var index = 0; index !== parameters.length; ++index) { | |
var parameter = parameters[index]; | |
var needed = argsNeeded[parameter]; | |
if (needed > values.length) { | |
if (parameter in defaults) { | |
result[parameter] = defaults[parameter]; | |
} | |
} else { | |
result[parameter] = values[valueIndex]; | |
++valueIndex; | |
} | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment