如何在JavaScript / jQuery中实现重载?

How can implement overloading in JavaScript/jQuery?

我试图调用具有相同签名的函数。

示例:有两个同名函数:

1
2
3
4
5
6
7
    var obj1,obj2,obj3,obj4,obj5;
    function OpenBox(obj1,obj2){
    // code
    }
    function OpenBox(obj1,obj2,obj3,obj4,obj5){
    // code
    }

当我调用函数时,单击链接事件

1
 Open Box

当我点击上面的链接时,它正在调用函数openbox(obj1、obj2、obj3、obj4、obj5)

它应该是调用函数openbox(obj1,obj2)。

功能出了什么问题?


马顿有正确的想法。因为javascript没有输入,所以这些函数是等效的。你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
function OpenBox_impl1(obj1,obj2){
    // code
}
function OpenBox_impl2(obj1,obj2,obj3,obj4,obj5){
    // code
}

function OpenBox(obj1, obj2, obj3, obj4, obj5) {
    if(arguments.length == 2)
        return OpenBox_impl1(obj1, obj2);
    else
        return OpenBox_impl2(obj1,obj2,obj3,obj4,obj5);
}


javascript不能在同一范围内定义重复的函数。检查arguments.length为2或5。


问题是,您试图重载一个函数,但JavaScript不支持它。我认为你最好的选择是使用多态性。有关详细信息,请参阅本文:http://www.cyberminds.co.uk/blog/articles/polymonization-in-javascript.aspx


不能重载javascript中的函数。相反,将使用函数的最新定义版本,这就是为什么在您的情况下调用带有5个参数的版本(最后3个参数只是undefined)。

有几种方法可以解决这个问题,米科拉的回答中有一种是这样的。另一种方法是传入一个对象,然后在函数中检查该对象的内容(请参见此问题):

1
2
3
4
5
6
function foo(a, b, opts) {

}

foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals","bar":"tree"});

另一种选择是检查arguments.length

1
2
3
4
5
6
function foo(a, b) {
    if(arguments.length > 2) {
        var arg3 = arguments[3];
        //etc...
    }
}

@阿卜西克,

没有类似于C语言或Java的东西。javascript的行为是这样的

1
2
3
4
function Test(arg1 ,arg2 , arg3, arg4)
{

}

调用此函数时,可以使用以下方法调用

1
2
3
4
Test(arg1);
Test(arg1,arg2);
Test(arg1,arg2,arg3);
Test(arg1,arg2,arg3,arg4);

但是顺序很重要,所以你可以用上面的方法来实现。


在多态性中,您可以使用不同的签名方法,在JavaScript中,我们可以模拟多态性检查函数参数的类型并执行特定的任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var input = document.getElementById('data');
polymorphism(input);
polymorphism('Hello word 2');
polymorphism('hello word 3', 5);

function polymorphism(arg,arg1){
  var string = null;
  var sqr = 0;
  if(typeof arg === 'string'){
    string = 'arg type String:
'
+arg;
  }else if (arg.tagName && arg.tagName === 'INPUT'){
    string = 'arg type Input:
'
+arg.value;
  }
  if(arg1 && typeof arg1 === 'number'){
    sqr = arg1*arg1;
    alert(string + ' and sqr = '+sqr);
  }else {
    alert(string);
  }    
}

在jsFiddle中检查这个例子


一旦在ecmascript中定义了函数,该名称就会被锁定。但是,您可以将任意数量的参数传递给该函数,这样就可以在内部完成其余的工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function foo(arg1, arg2) {
    // any code that is needed regardless of param count

    if(arg2 !== undefined) {
        // run function with both arguments
        console.log(arguments);
    } else if(arg1 !== undefined) {
        // run function with one argument
    } else {
        // run function with no arguments
    }
}

foo(1);
foo(1,2);
foo(1,2,3);

有趣的注意:您可以传递函数声明中没有的额外参数。做一个argumentsconsole.log,你会看到里面的一切。arguments是一个object,它可以像输入array那样被访问/打字。