繁体   English   中英

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

[英]javascript: optional first argument in function

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

my_function = function(content, options) { action }

如果我这样调用函数:

my_function (options)

参数“选项”作为“内容”传递

我该如何解决这个问题,以便我可以同时传递两个参数或仅传递一个参数? 谢谢你

您必须决定要将单个参数视为哪个参数。 您不能同时将其视为contentoptions

我看到两种可能性:

  1. 要么更改参数的顺序,即function(options, content)
  2. 检查是否定义了options

     function(content, options) { if(typeof options === "undefined") { options = content; content = null; } //action }

    但是,您必须正确记录,如果您只向函数传递一个参数会发生什么,因为通过查看签名并不能立即清楚这一点。

my_function = function(hash) { /* use hash.options and hash.content */ };

然后调用:

my_function ({ options: options });
my_function ({ options: options, content: content });

像这样:

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

使用 ES6:

function test(a, b = 3) {
   console.log(a, ' ', b);
}

test(1);      // Output: 1 3
test(1, 2);   // Output: 1 2

或者,您也可以根据获得的内容类型进行区分。 选项曾经是一个对象,内容曾经是一个字符串,所以你可以说:

if ( typeof content === "object" ) {
  options = content;
  content = null;
}

或者,如果您对重命名感到困惑,您可以使用更直接的参数数组:

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

此处的 MDN 网站上对ES6 中的默认参数有很好的阅读。
在 ES6 中,您现在可以执行以下操作:

secondDefaultValue = 'indirectSecondDefaultValue';

function MyObject( param1 = 'firstDefaultValue', param2 = secondDefaultValue ){
    this.first = param1;
    this.second = param2;
}

您也可以按如下方式使用它:

var object = new MyObject( undefined, options );

这将为第一个param1和第二个param2options设置默认值'firstDefaultValue'

这里有一个小提琴演示

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

1)

function something(options) {
    var timeToLive = options.timeToLive || 200; // default to 200 if not set
    ...
}

2)

function something(timeToDie /*, timeToLive*/) {
    var timeToLive = arguments[1] || 200; // default to 200 if not set
    ..
}

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

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

我创建了一个简单的库,用于使用 JavaScript 函数处理可选参数,请参阅https://github.com/ovatto/argShim 该库是用 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 }

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

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

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)),那么我建议使用像ArgueJS这样的库。 我没有亲自使用它,但它看起来很有希望。

只是为了踢一匹死马,因为我不得不在两个或更多必需参数的中间实现一个可选参数。 使用arguments数组并使用最后一个作为必需的非可选参数。

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

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

或者您必须更改方法定义,例如

my_function = function(options, content) { action }

您还可以检查操作,例如: options = !options ? content : options options = !options ? content : options如果没有第二个参数传入,则将选项设置为第一个参数的选项,然后您只需将内容设置为 null (或忽略它,但是您想检查它)

像这样打电话

my_function ("", options);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM