如何最好地确定参数是否未发送到 JavaScript 函数

2022-08-30 00:30:31

我现在已经看到了2种方法来确定参数是否已传递给JavaScript函数。我想知道一种方法是否比另一种方法更好,或者一种方法是否只是使用起来很糟糕?

 function Test(argument1, argument2) {
      if (Test.arguments.length == 1) argument2 = 'blah';

      alert(argument2);
 }

 Test('test');

 function Test(argument1, argument2) {
      argument2 = argument2 || 'blah';

      alert(argument2);
 }

 Test('test');

据我所知,它们都会产生相同的结果,但我之前只在生产中使用过第一个。

汤姆提到的另一种选择:

function Test(argument1, argument2) {
    if(argument2 === null) {
        argument2 = 'blah';
    }

    alert(argument2);
}

根据胡安的评论,最好将汤姆的建议改为:

function Test(argument1, argument2) {
    if(argument2 === undefined) {
        argument2 = 'blah';
    }

    alert(argument2);
}

答案 1

有几种不同的方法可以检查参数是否已传递给函数。除了您在(原始)问题中提到的两个问题 - 检查或使用运算符提供默认值 - 还可以显式检查via或是否有偏执狂的参数(请参阅注释)。arguments.length||undefinedargument2 === undefinedtypeof argument2 === 'undefined'

使用运算符已成为标准做法 - 所有很酷的孩子都这样做 - 但要小心:如果参数计算结果为,则将触发默认值,这意味着它实际上可能是,,,,(或其他任何返回的内容)。||falseundefinednullfalse0''Boolean(...)false

因此,问题是何时使用哪种检查,因为它们产生的结果略有不同。

检查表现出“最正确”的行为,但如果有多个可选参数,则可能不可行。arguments.length

的测试是下一个“最佳”的 - 只有当函数被显式调用时,它才会“失败”,并且很可能应该以与省略参数相同的方式处理该值。undefinedundefined

即使提供了有效参数,使用运算符也可能会触发默认值的使用。另一方面,它的行为实际上可能是可取的。||

总结一下:只有当你知道自己在做什么时才使用它!

在我看来,如果有多个可选参数,并且不希望将对象文本作为命名参数的解决方法,则使用也是要走的路。||

另一种提供默认值的好方法是通过掉落开关语句的标签来实现的:arguments.length

function test(requiredArg, optionalArg1, optionalArg2, optionalArg3) {
    switch(arguments.length) {
        case 1: optionalArg1 = 'default1';
        case 2: optionalArg2 = 'default2';
        case 3: optionalArg3 = 'default3';
        case 4: break;
        default: throw new Error('illegal argument count')
    }
    // do stuff
}

这有一个缺点,即程序员的意图不是(视觉上)明显,而是使用“幻数”;因此,它可能容易出错。


答案 2

如果您使用的是jQuery,那么一个不错的选项(特别是对于复杂情况)是使用jQuery的扩展方法

function foo(options) {

    default_options = {
        timeout : 1000,
        callback : function(){},
        some_number : 50,
        some_text : "hello world"
    };

    options = $.extend({}, default_options, options);
}

如果调用该函数,则如下所示:

foo({timeout : 500});

然后,选项变量将为:

{
    timeout : 500,
    callback : function(){},
    some_number : 50,
    some_text : "hello world"
};