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

当前回答

如果您正在使用jQuery,一个不错的选择(特别是对于复杂的情况)是使用jQuery的extend方法。

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"
};

其他回答

有时,您可能还想检查类型,特别是当您使用函数作为getter和setter时。下面的代码是ES6(不能在EcmaScript 5或更老版本中运行):

class PrivateTest {
    constructor(aNumber) {
        let _aNumber = aNumber;

        //Privileged setter/getter with access to private _number:
        this.aNumber = function(value) {
            if (value !== undefined && (typeof value === typeof _aNumber)) {
                _aNumber = value;
            }
            else {
                return _aNumber;
            }
        }
    }
}

有时你想要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

function example(arg) {
  var argumentID = '0'; //1,2,3,4...whatever
  if (argumentID in arguments === false) {
    console.log(`the argument with id ${argumentID} was not passed to the function`);
  }
}

因为数组继承自Object.prototype。想让世界更美好。

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

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以外的值,那么你可能需要对第一个参数进行一些更改;如果需要一个非零、非空、非空的值,那么第二种方法是理想的——实际上,它经常被用来快速地从考虑中消除如此广泛的值。

fnCalledFunction (Param1 Param2 window.YourOptionalParameter)

如果上面的函数是从很多地方调用的,并且你确定前两个参数是从每个地方传递的,但不确定第三个参数,那么你可以使用window。

窗口。如果它没有从调用方方法中定义,Param3将进行处理。