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

我现在已经看到了两种确定参数是否已经传递给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);
}

有几种不同的方法来检查参数是否传递给函数。 除了你在(原始)问题中提到的两个 - 检查arguments.length或使用|| 运算符提供默认值 - 也可以通过argument2 === undefinedtypeof argument2 === 'undefined'显式检查undefined的参数,如果一个是偏执的(参见注释)。

使用|| 操作符已经成为标准实践 - 所有酷酷的孩子都这样做 - 但要小心:如果参数的计算结果为false ,这意味着它可能实际上是undefinednullfalse0'' (或其他任何东西其中Boolean(...)返回false )。

所以问题是何时使用哪种检查,因为它们都会产生稍微不同的结果。

检查arguments.length显示'最正确的'行为,但如果有多个可选参数,则它可能不可行。

undefined的测试接下来是“最好的” - 如果函数被明确地调用一个undefined值,那么它只会“失败”,在所有可能的情况下,应该以与忽略参数相同的方式对待它。

使用|| 即使提供了有效的参数,操作员也可能会触发默认值的使用。 另一方面,其行为实际上可能是需要的。

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

在我看来,使用|| 如果有多个可选参数并且不想传递一个对象字面量作为命名参数的解决方法,那么这也是一种方法。

通过使用switch语句的标签来提供使用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
}

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


如果您使用的是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"
};

这是我找到测试的少数案例之一:

if(! argument2) {  

}

工作得很好,语法上带有正确的含义。

(同时限制我不允许一个合法的null值用于argument2 ,它具有其他含义;但那样会让人感到困惑。)

编辑:

这是松散类型语言和强类型语言之间风格差异的一个很好的例子; 以及JavaScript在黑桃中提供的风格选项。

我个人的偏好(没有批评意味着其他偏好)是极简主义。 代码越少说,只要我一致和简洁,越少其他人必须理解正确地推断我的意思。

这种偏好的一个含义是,我不希望 - 发现它有用 - 堆积一堆类型依赖性测试。 相反,我试图让代码意味着它的外观。 并只测试我真正需要测试的内容。

我在其他人的代码中发现的一个加重点是需要弄清楚他们是否期望在更大范围内实际遇到他们正在测试的案例。 或者,如果他们试图对所有可能的事情进行测试,那么他们有可能完全没有预测到上下文。 这意味着我最终需要在两个方向上详尽地追踪它们,然后才能自信地重构或修改任何内容。 我认为他们很可能已经进行了各种测试,因为他们预见到了他们需要的情况(通常对我而言这些情况并不明显)。

(我认为这些人使用动态语言的方式是一个严重的缺点,人们往往不想放弃所有的静态测试,最终伪造它。)

我最明显的看到,比较全面的ActionScript 3代码和优雅的JavaScript代码。 AS3可能是js的3到4倍,而我怀疑的可靠性至少不会更好,只是因为编码决策的数量(3-4X)。

正如你所说,Shog9,YMMV。 :d

链接地址: http://www.djcxy.com/p/77451.html

上一篇: How best to determine if an argument is not sent to the JavaScript function

下一篇: How can I remove the decimal part from JavaScript number?