用于可选/默认参数的轻量级JavaScript模块
是否有一个JavaScript模块可以轻松地将参数映射到参数?以下是我对其工作的设想: 变量参数=赋值参数(参数'p1','p2',[{'p3':0}, 'p4'],{'p5':'unknown'}) 在函数中,您可以调用它来生成一个对象,该对象将一个参数与一个参数相关联。数组或内联对象中定义的参数将被视为可选参数,其中内联对象将允许指定默认值。所有其他参数均被视为“必需” 以下是一些输入/输出示例:用于可选/默认参数的轻量级JavaScript模块,javascript,optional-parameters,default-parameters,Javascript,Optional Parameters,Default Parameters,是否有一个JavaScript模块可以轻松地将参数映射到参数?以下是我对其工作的设想: 变量参数=赋值参数(参数'p1','p2',[{'p3':0}, 'p4'],{'p5':'unknown'}) 在函数中,您可以调用它来生成一个对象,该对象将一个参数与一个参数相关联。数组或内联对象中定义的参数将被视为可选参数,其中内联对象将允许指定默认值。所有其他参数均被视为“必需” 以下是一些输入/输出示例: foo(1): { p1: 1, p3: 0, p5: 'unknown' } // no p
foo(1): { p1: 1, p3: 0, p5: 'unknown' } // no p2 (aka undefined)
foo(1, 2): { p1: 1, p2: 2, p3: 0, p5: 'unknown' }
foo(1, 2, 3): { p1: 1, p2: 2, p3: 0, p4: 3, p5: 'unknown' }
foo(1, 2, 3, 4): { p1: 1, p2: 2, p3: 3, p4: 4, p5: 'unknown' }
foo(1, 2, 3, 4, 5): { p1: 1, p2: 2, p3: 3, p4: 4, p5: 5 }
我希望这样的图书馆已经存在。这种逻辑会重复很多次,如果可能的话,我想消除它
有人知道这样的图书馆吗?如果没有,有人能让我走上正确的道路来实现它吗?我自己想了一个方法。它涉及到解析由字符串、数组和对象组成的对象图。它很长,但效果很好
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;
}
我会使用coffeescript,它已经实现了这一点。
function foo() {
var params = assignArguments(arguments, ['p1', 'p2', [{p3:0}, 'p4'], {p5: 'unknown'}]);
return params;
}
console.log(foo(1));
console.log(foo(1, 2));
console.log(foo(1, 2, 3));
console.log(foo(1, 2, 3, 4));
console.log(foo(1, 2, 3, 4, 5));