我有一个带有一些参数的典型Javascript函数。
my_function = function(content, options) { action }
如果我这样调用函数:
my_function (options)
参数"options"被传递为"content"
我该如何解决这个问题,以便可以同时传递两个参数或只传递一个参数? 谢谢
我有一个带有一些参数的典型Javascript函数。
my_function = function(content, options) { action }
如果我这样调用函数:
my_function (options)
参数"options"被传递为"content"
我该如何解决这个问题,以便可以同时传递两个参数或只传递一个参数? 谢谢
您需要决定将一个单一参数作为哪个参数来处理。您不能同时将其视为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
With 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;
}
var optional_arg = arguments.length >= 1 ? arguments[0] : '默认值';
- Richard Davies关于ES6中的默认参数有一篇很不错的文章,你可以在MDN网站上查看。在ES6中,现在可以进行如下操作:
secondDefaultValue = 'indirectSecondDefaultValue';
function MyObject( param1 = 'firstDefaultValue', param2 = secondDefaultValue ){
this.first = param1;
this.second = param2;
}
var object = new MyObject( undefined, options );
这将为第一个param1
设置默认值'firstDefaultValue'
,并将您的options
用于第二个param2
。
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 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
..
}
options
是一个JS对象,其中包含所需的任何属性。这样更易于维护和扩展。只是为了再次强调一下,因为我不得不在两个或多个必需参数中间实现一个可选参数。使用arguments
数组,并将最后一个用作必需的非可选参数。
my_function() {
var options = arguments[argument.length - 1];
var content = arguments.length > 1 ? arguments[0] : 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);
}
my_func(function () {});
=> options: {}
=> callback: function() {}
my_func({param1: 'param1', param2: 'param2'}, function () {});
=> options: {param1: "param1", param2: "param2"}
=> callback: function() {}
typeof
总是返回一个字符串。另外,if (options === undefined)
也可以起作用。但正如你所说,旧版浏览器中可能会覆盖undefined
,因此仍然普遍的做法是不直接使用undefined
(除非你在某个地方明确定义了)。 - Felix Kling===
来比较字符串,即使它们具有相同的内容,也不一定是同一个对象。 - inetphantomcontent
和options
的类型不同,可以检查content
的类型并进行交换。我也看到有人计算参数来实现这一点。检查content
而不是options
还提供了一些额外的参数验证。 - DKebler