[英]javascript: optional first argument in function
我有一个带有一些参数的典型 javascript 函数
my_function = function(content, options) { action }
如果我这样调用函数:
my_function (options)
参数“选项”作为“内容”传递
我该如何解决这个问题,以便我可以同时传递两个参数或仅传递一个参数? 谢谢你
您必须决定要将单个参数视为哪个参数。 您不能同时将其视为content
和options
。
我看到两种可能性:
function(options, content)
检查是否定义了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
和第二个param2
的options
设置默认值'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.