在Javascript中伪造函数重载的最好方法是什么?
我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:
一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?
在Javascript中伪造函数重载的最好方法是什么?
我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:
一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?
当前回答
第一个选项确实值得注意,因为这是我在相当复杂的代码设置中遇到的问题。所以,我的答案是
一开始就用不同的名字
有一个小但重要的提示,名称应该看起来不同的计算机,但不是你。命名重载函数,如func, func1, func2。
其他回答
我经常这样做:
C#:
public string CatStrings(string p1) {return p1;}
public string CatStrings(string p1, int p2) {return p1+p2.ToString();}
public string CatStrings(string p1, int p2, bool p3) {return p1+p2.ToString()+p3.ToString();}
CatStrings("one"); // result = one
CatStrings("one",2); // result = one2
CatStrings("one",2,true); // result = one2true
JavaScript相当于:
function CatStrings(p1, p2, p3)
{
var s = p1;
if(typeof p2 !== "undefined") {s += p2;}
if(typeof p3 !== "undefined") {s += p3;}
return s;
};
CatStrings("one"); // result = one
CatStrings("one",2); // result = one2
CatStrings("one",2,true); // result = one2true
This particular example is actually more elegant in javascript than C#. Parameters which are not specified are 'undefined' in javascript, which evaluates to false in an if statement. However, the function definition does not convey the information that p2 and p3 are optional. If you need a lot of overloading, jQuery has decided to use an object as the parameter, for example, jQuery.ajax(options). I agree with them that this is the most powerful and clearly documentable approach to overloading, but I rarely need more than one or two quick optional parameters.
编辑:根据Ian的建议更改IF测试
因为这篇文章已经包含了很多不同的解决方案,所以我想再发一个。
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
function overload() {
var functions = arguments;
var nroffunctionsarguments = [arguments.length];
for (var i = 0; i < arguments.length; i++) {
nroffunctionsarguments[i] = arguments[i].length;
}
var unique = nroffunctionsarguments.filter(onlyUnique);
if (unique.length === arguments.length) {
return function () {
var indexoffunction = nroffunctionsarguments.indexOf(arguments.length);
return functions[indexoffunction].apply(this, arguments);
}
}
else throw new TypeError("There are multiple functions with the same number of parameters");
}
这可以使用如下所示:
var createVector = overload(
function (length) {
return { x: length / 1.414, y: length / 1.414 };
},
function (a, b) {
return { x: a, y: b };
},
function (a, b,c) {
return { x: a, y: b, z:c};
}
);
console.log(createVector(3, 4));
console.log(createVector(3, 4,5));
console.log(createVector(7.07));
这个解决方案不是完美的,但我只想演示它是如何做到的。
Javascript中的函数重载:
函数重载是一种编程语言用不同的实现创建多个同名函数的能力。当重载函数被调用时,它将运行该函数的特定实现,以适应调用的上下文。这个上下文通常是接收参数的数量,它允许一个函数调用根据上下文表现不同。
Javascript没有内置的函数重载。然而,这种行为可以通过许多方式来模仿。这里有一个简单方便的例子:
函数sayHi(a, b) { Console.log ('hi there ' + a); 如果(b) {console.log('and ' + b)} //如果参数存在,则执行该块 } sayHi(“弗兰克”,“威廉”);
在你不知道你将得到多少参数的情况下,你可以使用rest操作符,即三点....它将把剩余的参数转换为一个数组。但是要注意浏览器的兼容性。这里有一个例子:
函数foo (a,…b) { console.log (b); } foo(1、2、3、4); foo(1、2);
我刚试过了,也许能满足你的需要。 根据参数的数量,您可以访问不同的函数。在第一次调用时初始化它。 函数映射隐藏在闭包中。
TEST = {};
TEST.multiFn = function(){
// function map for our overloads
var fnMap = {};
fnMap[0] = function(){
console.log("nothing here");
return this; // support chaining
}
fnMap[1] = function(arg1){
// CODE here...
console.log("1 arg: "+arg1);
return this;
};
fnMap[2] = function(arg1, arg2){
// CODE here...
console.log("2 args: "+arg1+", "+arg2);
return this;
};
fnMap[3] = function(arg1,arg2,arg3){
// CODE here...
console.log("3 args: "+arg1+", "+arg2+", "+arg3);
return this;
};
console.log("multiFn is now initialized");
// redefine the function using the fnMap in the closure
this.multiFn = function(){
fnMap[arguments.length].apply(this, arguments);
return this;
};
// call the function since this code will only run once
this.multiFn.apply(this, arguments);
return this;
};
测试它。
TEST.multiFn("0")
.multiFn()
.multiFn("0","1","2");
如果我需要一个函数与两个使用foo(x)和foo(x,y,z)哪种是最好的/首选的方式?
问题是JavaScript本身不支持方法重载。因此,如果它看到/解析了两个或多个同名的函数,它只会考虑最后定义的函数,并覆盖之前的函数。
我认为适用于大多数情况的一种方法是
假设你有方法
function foo(x)
{
}
而不是重载方法,这在javascript中是不可能的,你可以定义一个新的方法
fooNew(x,y,z)
{
}
然后将第一个函数修改为-
function foo(arguments)
{
if(arguments.length==2)
{
return fooNew(arguments[0], arguments[1]);
}
}
如果你有很多这样的重载方法,考虑使用switch而不是If -else语句。