在javascript中处理可选参数

jd.*_*jd. 127 javascript

我有一个静态的javascript函数,可以采用1,2或3个参数:

function getData(id, parameters, callback) //parameters (associative array) and callback (function) are optional
Run Code Online (Sandbox Code Playgroud)

我知道我总是可以测试给定参数是否未定义,但我怎么知道传递的是参数还是回调?

这样做的最佳方法是什么?


可以传递的内容示例:

1:

getData('offers');
Run Code Online (Sandbox Code Playgroud)

2:

var array = new Array();
array['type']='lalal';
getData('offers',array);
Run Code Online (Sandbox Code Playgroud)

3:

var foo = function (){...}
getData('offers',foo);
Run Code Online (Sandbox Code Playgroud)

4:

getData('offers',array,foo);
Run Code Online (Sandbox Code Playgroud)

CMS*_*CMS 163

您可以知道有多少参数传递给您的函数,您可以检查您的第二个参数是否是函数:

function getData (id, parameters, callback) {
  if (arguments.length == 2) { // if only two arguments were supplied
    if (Object.prototype.toString.call(parameters) == "[object Function]") {
      callback = parameters; 
    }
  }
  //...
}
Run Code Online (Sandbox Code Playgroud)

您也可以这样使用arguments对象:

function getData (/*id, parameters, callback*/) {
  var id = arguments[0], parameters, callback;

  if (arguments.length == 2) { // only two arguments supplied
    if (Object.prototype.toString.call(arguments[1]) == "[object Function]") {
      callback = arguments[1]; // if is a function, set as 'callback'
    } else {
      parameters = arguments[1]; // if not a function, set as 'parameters'
    }
  } else if (arguments.length == 3) { // three arguments supplied
      parameters = arguments[1];
      callback = arguments[2];
  }
  //...
}
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣,请参阅John Resig 撰写的关于模拟JavaScript上方法重载的技术的文章.


med*_*iev 75

呃 - 这意味着你正在使用不正确顺序的参数来调用你的函数......我不建议这样做.

我建议改为将一个对象提供给你的函数,如下所示:

function getData( props ) {
    props = props || {};
    props.params = props.params || {};
    props.id = props.id || 1;
    props.callback = props.callback || function(){};
    alert( props.callback )
};

getData( {
    id: 3,
    callback: function(){ alert('hi'); }
} );
Run Code Online (Sandbox Code Playgroud)

优点:

  • 你不必考虑争论的顺序
  • 你不必进行类型检查
  • 定义默认值更容易,因为不需要进行类型检查
  • 少头痛.想象一下,如果你添加了第四个参数,你必须每次更新你的类型检查,如果第四个或连续也是函数怎么办?

缺点:

  • 重构代码的时间

如果您别无选择,可以使用函数来检测对象是否确实是一个函数(参见上一个示例).

注意:这是检测函数的正确方法:

function isFunction(obj) {
    return Object.prototype.toString.call(obj) === "[object Function]";
}

isFunction( function(){} )
Run Code Online (Sandbox Code Playgroud)