在Javascript中伪造函数重载的最好方法是什么?
我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:
一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?
在Javascript中伪造函数重载的最好方法是什么?
我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:
一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?
当前回答
你可以使用John Resig的addMethod。使用此方法,您可以根据参数计数“重载”方法。
// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn){
var old = object[ name ];
object[ name ] = function(){
if ( fn.length == arguments.length )
return fn.apply( this, arguments );
else if ( typeof old == 'function' )
return old.apply( this, arguments );
};
}
我还创建了该方法的替代方法,使用缓存来保存函数的变体。这里描述了不同之处
// addMethod - By Stavros Ioannidis
function addMethod(obj, name, fn) {
obj[name] = obj[name] || function() {
// get the cached method with arguments.length arguments
var method = obj[name].cache[arguments.length];
// if method exists call it
if ( !! method)
return method.apply(this, arguments);
else throw new Error("Wrong number of arguments");
};
// initialize obj[name].cache
obj[name].cache = obj[name].cache || {};
// Check if a method with the same number of arguments exists
if ( !! obj[name].cache[fn.length])
throw new Error("Cannot define multiple '" + name +
"' methods with the same number of arguments!");
// cache the method with fn.length arguments
obj[name].cache[fn.length] = function() {
return fn.apply(this, arguments);
};
}
其他回答
在javascript中没有办法实现函数重载。 因此,我推荐使用下面的by typeof()方法而不是 多重功能伪造过载。
function multiTypeFunc(param)
{
if(typeof param == 'string') {
alert("I got a string type parameter!!");
}else if(typeof param == 'number') {
alert("I got a number type parameter!!");
}else if(typeof param == 'boolean') {
alert("I got a boolean type parameter!!");
}else if(typeof param == 'object') {
alert("I got a object type parameter!!");
}else{
alert("error : the parameter is undefined or null!!");
}
}
好运!
用形参重载函数的最好方法不是检查实参长度或类型;检查类型只会让你的代码变慢,你可以享受数组、空值、对象等的乐趣。
大多数开发人员所做的是将一个对象作为方法的最后一个参数。这个物体可以装任何东西。
function foo(a, b, opts) {
// ...
if (opts['test']) { } //if test param exists, do something..
}
foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});
然后你可以在你的方法中任意处理它。[开关,if-else,等等]
我喜欢@AntouanK的方法。我经常发现自己提供了一个具有不同数量参数和不同类型的函数。有时他们不服从命令。我用来映射查找参数类型:
findUDPServers: function(socketProperties, success, error) {
var fqnMap = [];
fqnMap['undefined'] = fqnMap['function'] = function(success, error) {
var socketProperties = {name:'HELLO_SERVER'};
this.searchServers(socketProperties, success, error);
};
fqnMap['object'] = function(socketProperties, success, error) {
var _socketProperties = _.merge({name:'HELLO_SERVER'}, socketProperties || {});
this.searchServers(_socketProperties, success, error);
};
fqnMap[typeof arguments[0]].apply(this, arguments);
}
JavaScript是一种无类型语言,我认为只有在参数数量方面重载方法/函数才有意义。因此,我建议检查参数是否已经定义:
myFunction = function(a, b, c) {
if (b === undefined && c === undefined ){
// do x...
}
else {
// do y...
}
};
我们用over.js来解决这个问题是一种非常优雅的方式。你可以:
var obj = {
/**
* Says something in the console.
*
* say(msg) - Says something once.
* say(msg, times) - Says something many times.
*/
say: Over(
function(msg$string){
console.info(msg$string);
},
function(msg$string, times$number){
for (var i = 0; i < times$number; i++) this.say(msg$string);
}
)
};