我已经看到了两种方法,用于确定参数是否已传递给JavaScript函数。我想知道是一种方法比另一种好,还是一种方法不好用?

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

      alert(argument2);
 }

 Test('test');

Or

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

      alert(argument2);
 }

 Test('test');

据我所知,它们的结果是一样的,但我以前在生产中只使用过第一个。

Tom提到的另一个选择:

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

    alert(argument2);
}

根据Juan的评论,Tom的建议最好改为:

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

    alert(argument2);
}

当前回答

有时你想要undefined作为一个可能的参数,但你仍然有可能不传递参数的情况。在这种情况下,你可以使用参数。长度来检查传递了多少个参数。


// Throw error if the field is not matching our expectations
function testField(label, fieldValue, expectedValue) {
    console.log(arguments) // Gives: [Arguments] { '0': 'id', '1': 1, '2': undefined }
    if(arguments.length === 2) {
        if(!fieldValue) {
            throw new Error(`Field "${label}" must have a value`)
        }
    }

    else if(expectedValue === undefined) {
        if(fieldValue !== undefined) {
            throw Error(`Field "${label}" must NOT have a value`)
        }
    }

    // We stringify so our check works for objects as well
    else {
        if(JSON.stringify(fieldValue) !== JSON.stringify(expectedValue)) {
            throw Error(`Field "${label}" must equal ${expectedValue} but was ${fieldValue}`)
        }
    }
}

testField('id', 12) ->传递,我们不希望id为空

testField('id', undefined, undefined) ->通过,我们希望id为undefined

testField('id', 12, undefined) ->错误,我们希望id是undefined

其他回答

有时你想要undefined作为一个可能的参数,但你仍然有可能不传递参数的情况。在这种情况下,你可以使用参数。长度来检查传递了多少个参数。


// Throw error if the field is not matching our expectations
function testField(label, fieldValue, expectedValue) {
    console.log(arguments) // Gives: [Arguments] { '0': 'id', '1': 1, '2': undefined }
    if(arguments.length === 2) {
        if(!fieldValue) {
            throw new Error(`Field "${label}" must have a value`)
        }
    }

    else if(expectedValue === undefined) {
        if(fieldValue !== undefined) {
            throw Error(`Field "${label}" must NOT have a value`)
        }
    }

    // We stringify so our check works for objects as well
    else {
        if(JSON.stringify(fieldValue) !== JSON.stringify(expectedValue)) {
            throw Error(`Field "${label}" must equal ${expectedValue} but was ${fieldValue}`)
        }
    }
}

testField('id', 12) ->传递,我们不希望id为空

testField('id', undefined, undefined) ->通过,我们希望id为undefined

testField('id', 12, undefined) ->错误,我们希望id是undefined

url = url === undefined ? location.href : url;

两者存在显著差异。让我们建立一些测试用例:

var unused; // value will be undefined
Test("test1", "some value");
Test("test2");
Test("test3", unused);
Test("test4", null);
Test("test5", 0);
Test("test6", "");

使用您描述的第一个方法,只有第二个测试将使用默认值。第二个方法将默认除第一个方法外的所有方法(因为JS将把undefined、null、0和""转换为布尔值false。如果您使用Tom的方法,那么只有第四个测试将使用默认的方法!

你选择哪种方法实际上取决于你的预期行为。如果参数2允许使用undefined以外的值,那么你可能需要对第一个参数进行一些更改;如果需要一个非零、非空、非空的值,那么第二种方法是理想的——实际上,它经常被用来快速地从考虑中消除如此广泛的值。

在ES6 (ES2015)中,您可以使用默认参数

function Test(arg1 = 'Hello', arg2 = 'World!'){ Alert (arg1 + ' ' +arg2); } 测试('你好','世界! ');// Hello World! 测试('你好');// Hello World! 测试();// Hello World!

这是我发现的少数几个测试案例之一:

if(! argument2) {  

}

工作得很好,并且在语法上具有正确的含义。

(同时限制我不允许argument2有一个合法的空值,它有一些其他的含义;但这真的会让人困惑。)

编辑:

这是一个很好的例子,说明了松散类型语言和强类型语言之间的风格差异;这是javascript提供的一种风格选择。

我个人的偏好是极简主义(对其他偏好没有批评)。只要我是一致和简洁的,代码需要表达的越少,其他人就需要理解的越少,从而正确地推断出我的意思。

这种偏好的一个暗示是,我不想——也不认为它有用——堆积一堆类型依赖的测试。相反,我试图让代码的意思像它看起来的那样;只测试我真正需要测试的东西。

One of the aggravations I find in some other peoples' code is needing to figure out whether or not they expect, in the larger context, to actually run into the cases they are testing for. Or if they are trying to test for everything possible, on the chance that they don't anticipate the context completely enough. Which means I end up needing to track them down exhaustively in both directions before I can confidently refactor or modify anything. I figure that there's a good chance they might have put those various tests in place because they foresaw circumstances where they would be needed (and which usually aren't apparent to me).

(我认为这是这些人使用动态语言的一个严重缺点。人们经常不愿意放弃所有的静态测试,最终以假装测试而告终。)

在比较全面的ActionScript 3代码和优雅的javascript代码时,我最清楚地看到了这一点。AS3可以是js的3到4倍,我怀疑可靠性至少不会更好,只是因为所做的编码决策的数量(3-4倍)。

如你所说,Shog9, YMMV。: D