javascript:函数中可选的第一个参数

javascript:函数中可选的第一个参数,javascript,Javascript,我有一个带有一些参数的典型javascript函数 my_function = function(content, options) { action } 如果我这样调用函数: my_function (options) 参数“options”作为“content”传递 我该如何处理这个问题,这样我既可以传递两个参数,也可以只传递一个参数? 谢谢你这样说: my_function (null, options) // for options only my_function (content

我有一个带有一些参数的典型javascript函数

my_function = function(content, options) { action }
如果我这样调用函数:

my_function (options)
参数“options”作为“content”传递

我该如何处理这个问题,这样我既可以传递两个参数,也可以只传递一个参数? 谢谢你这样说:

my_function (null, options) // for options only
my_function (content) // for content only
my_function (content, options) // for both

您将得到未传递的参数值为未定义。 但在您的情况下,必须在第一个参数中至少传递null值

my_function() {
  var options = arguments[argument.length - 1];
  var content = arguments.length > 1 ? arguments[0] : null;
}
或者您必须更改方法定义,如

my_function = function(options, content) { action }
然后打电话:

my_function ({ options: options });
my_function ({ options: options, content: content });
像这样打电话

my_function ("", options);

您必须决定要处理单个参数的参数。您不能将其同时视为
内容
选项

我认为有两种可能性:

  • 或者更改参数的顺序,即
    函数(选项、内容)
  • 检查是否定义了
    选项

    function(content, options) {
        if(typeof options === "undefined") {
            options = content;
            content = null;
        }
        //action
    }
    
    但是,您必须正确地记录,如果只向函数传递一个参数,会发生什么情况,因为通过查看签名,这并不能立即清楚


  • 或者你也可以根据你得到的内容类型来区分。选项过去是一个对象内容过去是一个字符串,因此您可以说:

    if ( typeof content === "object" ) {
      options = content;
      content = null;
    }
    
    或者,如果您对重命名感到困惑,可以使用参数数组,该数组可以更简单:

    if ( arguments.length === 1 ) {
      options = arguments[0];
      content = null;
    }
    

    可以将对象中的所有可选参数作为第一个参数传递。第二个参数是回调。现在,您可以在第一个参数对象中接受任意数量的参数,并将其设置为可选,如下所示:

    function my_func(op, cb) {
        var options = (typeof arguments[0] !== "function")? arguments[0] : {},
            callback = (typeof arguments[0] !== "function")? arguments[1] : arguments[0];
    
        console.log(options);
        console.log(callback);
    }
    
    如果在不传递options参数的情况下调用它,它将默认为空对象:

    my_func(function () {});
    => options: {}
    => callback: function() {}
    
    如果使用options参数调用它,则会得到所有参数:

    my_func({param1: 'param1', param2: 'param2'}, function () {});
    => options: {param1: "param1", param2: "param2"}
    => callback: function() {}
    

    很明显,可以对其进行调整,以处理多于两个的参数,但它会变得更加混乱。如果您可以只使用一个对象作为第一个参数,那么您可以使用该对象传递无限数量的参数。如果您绝对需要更多可选参数(例如my_func(arg1,arg2,arg3,…,arg10,fn)),那么我建议使用类似的库。我个人没有用过,但看起来很有希望

    您还可以在操作中进行检查,如:
    options=!选择?内容:选项

    如果没有传入第二个参数,则将选项设置为第一个参数,然后您只需将内容设置为null(或者忽略它,但您需要检查它)

    有两种方法可以做到这一点

    (一)

    (二)

    在1)中,
    options
    是一个JS对象,具有所需的任何属性。这更易于维护和扩展


    在2)中,函数签名清晰易读,可以提供第二个参数。我在Mozilla代码和文档中见过这种风格。

    我创建了一个简单的库,用于处理JavaScript函数的可选参数,请参阅。该库的开发考虑了Node.js,但应易于移植,以便与浏览器等一起使用

    例如:

    var argShim = require('argShim');
    var defaultOptions = {
      myOption: 123
    };
    
    var my_function = argShim([
        {optional:'String'},
        {optional:'Object',default:defaultOptions}
      ], function(content, options) {
        console.log("content:", content, "options:", options);
      });
    
    my_function();
    my_function('str');
    my_function({myOption:42});
    my_function('str', {myOption:42});
    
    输出:

    content: undefined options: { myOption: 123 }
    content: str options: { myOption: 123 }
    content: undefined options: { myOption: 42 }
    content: str options: { myOption: 42 }
    

    库的主要目标是模块接口,您需要能够处理导出的模块函数的不同调用。

    只是要踢一个长期枯死的马,因为我必须在两个或更多所需的参数中间实现一个可选的参数。使用

    参数
    数组,并使用最后一个作为必需的非可选参数

    my_function() {
      var options = arguments[argument.length - 1];
      var content = arguments.length > 1 ? arguments[0] : null;
    }
    

    ES6中的默认参数有一个很好的解读
    在ES6中,您现在可以执行以下操作:

    secondDefaultValue = 'indirectSecondDefaultValue';
    
    function MyObject( param1 = 'firstDefaultValue', param2 = secondDefaultValue ){
        this.first = param1;
        this.second = param2;
    }
    
    您也可以按如下方式使用此选项:

    var object = new MyObject( undefined, options );
    
    这将为第一个
    param1
    设置默认值
    'firstDefaultValue'
    ,为第二个
    param2
    设置
    选项

    使用ES6时:

    function test(a, b = 3) {
       console.log(a, ' ', b);
    }
    
    test(1);      // Output: 1 3
    test(1, 2);   // Output: 1 2
    

    @Muneer:这只是一个例子。肯定是ruby背景的标志。@FrontierPsycho或Perl。@BlueBird hash只是指Darin等同于Javascript对象的哈希表(也称为字典/关联数组)。我更喜欢这种变体:
    var optional\u arg=arguments.length>=1?参数[0]:“默认值”
    undefined是一个具有常量值的全局属性,因此不需要引用它。在过时的浏览器中,您可能会意外地将其设置为任意值,但现代浏览器并非如此。@Andrew:
    typeof
    始终返回字符串。或者,
    if(options===undefined)
    也可以工作。但正如您所说,在旧浏览器中可以覆盖
    未定义的
    ,因此仍然流行的做法(我认为)是不要直接使用
    未定义的
    (除非您在某个地方明确定义)。不要将字符串与
    ==
    进行比较,如果你的内容相同,就不一定是同一个对象。@inetmphantom:不知道你在说什么。那没有道理。基本字符串无论如何都不是对象。如果您知道
    内容
    选项
    的类型不同,您可以检查
    内容
    的类型,并在需要时进行交换。我也看到有人为了这个而计算论点。检查
    内容
    而不是
    选项
    也会提供一些额外的参数验证非常感谢。。。没错,我在找这个。我的函数中有6个参数。某些参数具有默认值。但有些参数应该在函数调用中设置。我认为这个答案非常适合我的情况。再次感谢……:)这是非常冗长的,而且它使用了“default”这个词,这个词在JS中已经是一个关键字了。不推荐。当然可能有点冗长,但它在简单的参数存在性检查基础上提供了一些附加功能。在每个函数中编写相同的特性肯定会更加冗长。另外,虽然有些人不喜欢它,但保留关键字可以在ES5中自由地用作属性名。然而,整个lib编写得相当匆忙,因此您(和我)的里程可能会有所不同:)
    var object = new MyObject( undefined, options );
    
    function test(a, b = 3) {
       console.log(a, ' ', b);
    }
    
    test(1);      // Output: 1 3
    test(1, 2);   // Output: 1 2