我发现 C# 中的命名参数功能在某些情况下非常有用。
calculateBMI(70, height: 175);
如果我想在 JavaScript 中使用它,我可以使用什么?
<小时/>我不想要的是这样的:
myFunction({ param1: 70, param2: 175 });
function myFunction(params){
// Check if params is an object
// Check if the parameters I need are non-null
// Blah blah
}
我已经使用过这种方法。还有别的办法吗?
我可以使用任何库来执行此操作。
最佳答案
ES2015 及更高版本
在 ES2015 中,parameter destructuring可用于模拟命名参数。它需要调用者传递一个对象,但如果您还使用 default parameters ,则可以避免函数内部的所有检查。 :
myFunction({ param1 : 70, param2 : 175});
function myFunction({param1, param2}={}){
// ...function body...
}
// Or with defaults,
function myFunc({
name = 'Default user',
age = 'N/A'
}={}) {
// ...function body...
}
<小时/>
ES5
有一种方法可以接近您想要的,但它基于 Function.prototype.toString
[ES5] 的输出,这在某种程度上依赖于实现,因此它可能不跨浏览器兼容。
这个想法是从函数的字符串表示中解析参数名称,以便您可以将对象的属性与相应的参数关联起来。
函数调用可能看起来像
func(a, b, {someArg: ..., someOtherArg: ...});
其中 a
和 b
是位置参数,最后一个参数是具有命名参数的对象。
例如:
var parameterfy = (function() {
var pattern = /function[^(]*\(([^)]*)\)/;
return function(func) {
// fails horribly for parameterless functions ;)
var args = func.toString().match(pattern)[1].split(/,\s*/);
return function() {
var named_params = arguments[arguments.length - 1];
if (typeof named_params === 'object') {
var params = [].slice.call(arguments, 0, -1);
if (params.length < args.length) {
for (var i = params.length, l = args.length; i < l; i++) {
params.push(named_params[args[i]]);
}
return func.apply(this, params);
}
}
return func.apply(null, arguments);
};
};
}());
您将使用它:
var foo = parameterfy(function(a, b, c) {
console.log('a is ' + a, ' | b is ' + b, ' | c is ' + c);
});
foo(1, 2, 3); // a is 1 | b is 2 | c is 3
foo(1, {b:2, c:3}); // a is 1 | b is 2 | c is 3
foo(1, {c:3}); // a is 1 | b is undefined | c is 3
foo({a: 1, c:3}); // a is 1 | b is undefined | c is 3
这种方法有一些缺点(已警告您!):
- 如果最后一个参数是一个对象,则将其视为“命名参数对象”
- 您始终会获得与函数中定义的参数一样多的参数,但其中一些参数可能具有值
undefined
(这与根本没有值不同)。这意味着您无法使用arguments.length
来测试已传递了多少个参数。
您还可以拥有一个接受函数和各种值作为参数的函数,而不是创建包装器的函数,例如
call(func, a, b, {posArg: ... });
甚至扩展Function.prototype
,以便您可以执行以下操作:
foo.execute(a, b, {posArg: ...});
关于javascript - 有没有办法在 JavaScript 的函数调用中提供命名参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48862708/