将参数传递给没有订单的函数

时间:2018-02-23 06:46:20

标签: javascript angularjs

我有这样的功能:

let showNotification = function(a,b,c,d,e,f){
  console.log(a,b,c,d,e,f);
}

在调用此函数时,我知道我需要遵循命令,类似这样的事情(如果我不想传递c,d,e的参数):

showNotification(1,2,,,,6);

但是这迫使我确保我传递所有参数,它应该是有序的..

我正在寻找一种更好的方法来传递param。

我知道我可以创建一个param对象而不是传递值。像这样的东西:

let showNotification = function(objectParam){
console.log(objectParam.a, objectParam.b, objectParam.c, objectParam.d, objectParam.e, objectParam.f)
}

然后调用它:

showNotification({a: 1, b: 2, e:6});

我可以传递整个对象,但这不是我想要的。我不希望每次都为此创建对象。

大声思考,如果有办法传递字符串值,而不需要处理顺序。

我看到一些关于此的死亡帖子,但没有人有解决方案。

3 个答案:

答案 0 :(得分:1)

TL; DR 我知道您不想使用对象,但现代JavaScript引擎在创建和处理对象时非常,并且使用参数默认值和参数解构,我认为选项对象是你最好的选择。有关详细信息,请参阅下面的“关于传入对象的注释(默认值,解构)”

您已经介绍了两个主要选项(我将在下面的传递对象版本中做一些注释)。第三种选择是采用构建器模式的变体,但它也涉及使用对象。你已经说过你不想这样做,但是没有说为什么没有。请注意,如果您担心这一点,现代JavaScript引擎会创建并处理对象真的非常快

标记字符串

在阅读Bhushan Babar's append/prepend idea时,我发现了第四个选项:您可以在参数列表中使用标记字符串来指示下一个参数是什么,例如:

showNotification("the required parameter", "a", value_for_a, "c", value_for_c);

乍一看,这不涉及创建对象,但在现代JavaScript引擎上,处理它创建一个未创建的对象:arguments,伪-array of pass-in arguments。因为那个(或者一个rest参数,它也创建了一个对象)是你可以消费这种东西的唯一合理方式。

Builder上的Variant

在这种方法中,main函数返回一个构建器对象,其中包含各种选项的setter,然后是最后一个“Yep,我们准备就绪”调用,启动该过程(在构建器模式中,最终调用通常构建最终对象)。使用它看起来像这样:

showNotification("the required param")
    .withA(value_for_a)
    .withC(value_for_c)
    .go();

相对于其他方法,实现这一点很复杂,但难以

传入对象的注释(默认,解构)

如果你确实使用了一个对象(尽管不想这样做),你可以使用default parametersdestructuring来使对象更方便使用:

let showNotification = function({a = 1, b = 2, c = 3, d = 4, e = 5, f = 6} = {/*default if no object at all*/a: "foo"}){
  console.log(a,b,c,d,e,f);
};

showNotification();
showNotification({});
showNotification({a:42});

你在评论中说过:

  

这里的东西都是可选的,除了第一个参数

听起来你可能想要第一个参数,然后是选项对象:

let showNotification = function(firstThing, {a = "default_a", b = "default_b"/*etc.*/} = {}) {
  console.log(firstThing, a, b);
};

答案 1 :(得分:1)

@T,J. Crowder回答说比这更好。换句话说,您可以使用spread Operators执行此操作。正如你所说the thing is here all are optional, except the first param。所以你应该传递第一个参数值。除非你想要,否则你不需要传递其他值。但是你应该在数组中将,的参数值的位置称为空。 In my case you should create an object or array.

  

例如。如果你有一个带有值的动态数组(除了位置应该是必需的)和位置[1,,,3]。然后,spread运算符有助于将该动态数组与您的函数参数合并。

let showNotification = function(a,b,c,d,e,f){
  console.log(a,b,c,d,e,f);
};

let parts = [2,3,,,6];//Think it is a dynamic array on run time or compile time
showNotification(1,...parts);

此处@Felix Kling答案可以通过Named Parameters

帮助

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 

更多例子:

Pass a value to a specific parameter without caring about the position of the parameter

Passing the argument name while calling function in javascript

JavaScript: Get Argument Value and NAME of Passed Variable

答案 2 :(得分:1)

Bhushan Babar尚未发布his suggestion作为答案,因此我会将其发布为社区维基:

  

你可以为你的字符串添加或附加(concat)各个参数的标记,例如,如果你想发送代表参数d的参数,你要传递的字符串是“myString”,那么你可以决定你的标记的格式比如$&amp; d&amp; $,所以你的参数看起来像“myString $&amp; d&amp; $”