javascript - 有没有办法在 JavaScript 的函数调用中提供命名参数?

标签 javascript function optional-parameters named-parameters

我发现 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: ...});

其中 ab 是位置参数,最后一个参数是具有命名参数的对象。

例如:

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 

DEMO

这种方法有一些缺点(已警告您!):

  • 如果最后一个参数是一个对象,则将其视为“命名参数对象”
  • 您始终会获得与函数中定义的参数一样多的参数,但其中一些参数可能具有值undefined(这与根本没有值不同)。这意味着您无法使用 arguments.length 来测试已传递了多少个参数。
<小时/>

您还可以拥有一个接受函数和各种值作为参数的函数,而不是创建包装器的函数,例如

call(func, a, b, {posArg: ... });

甚至扩展Function.prototype,以便您可以执行以下操作:

foo.execute(a, b, {posArg: ...});

关于javascript - 有没有办法在 JavaScript 的函数调用中提供命名参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48862708/

相关文章:

javascript - 没有在 firestore 中获取自定义文档

c - 是否有任何特定原因表明函数调用不应用于 C 中的变量初始值设定项

function - 戈朗 : custom template function "capture"

python - 如何将嵌套函数作为参数传递

c# - 显式实现的接口(interface)中的可选参数

javascript - 单击事件监听器在 OSX 的 Safari 中有效,但在 iOS 中无效

javascript - 下一个 JS 构建并不是构建每条路径

javascript - 如何在 html5 数据列表中使用 angularjs ng-click

C# - 使用 lambda 指定非默认参数

c# - 设置 C# 可选参数的默认值