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

Posted

技术标签:

【中文标题】如何在 JavaScript/jQuery 中实现重载?【英文标题】:How can implement overloading in JavaScript/jQuery? 【发布时间】:2011-09-21 19:19:36 【问题描述】:

我正在尝试调用具有相同签名的函数。

示例:有两个同名函数:

<script>
    var obj1,obj2,obj3,obj4,obj5;
    function OpenBox(obj1,obj2)
    // code
    
    function OpenBox(obj1,obj2,obj3,obj4,obj5)
    // code
    
</script>

当我在链接的点击事件上调用函数时

<a id='hlnk1' href='#' onclick='OpenBox(this,\"abhishek\"); return false;'> Open Box </a>

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

应该是调用函数OpenBox(obj1,obj2)代替。

函数出了什么问题?

【问题讨论】:

'OpenBox(this,\"abhishek\") return false;' 应该是 'OpenBox(this,"abhishek") return false;' 阅读这个问题的答案:***.com/questions/456177/… @lbu - 转义引号,虽然在这种情况下没有必要,但实际上并没有伤害它吗?我会更担心右括号和返回之间没有分号。 我只想指出,作为搜索的一部分阅读此问题的人们 Abhishek 所描述的称为方法重载,不是多态性。多态性是遵守特定接口或契约的能力。 javascript 是一种鸭式语言,具有隐含的多态性。 @Randolpho 感谢您的描述。 【参考方案1】:

mattn 的想法是正确的。因为 javascript 没有打字,所以这些功能是等效的。你可以做的是这样的:

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);

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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

有几种方法可以解决这个问题,其中一种方法显示在 Mikola 的回答中。另一种方法是传入一个对象,然后在函数中检查该对象的内容(参见this question):

function foo(a, b, opts) 



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

另一种选择是检查arguments.length

function foo(a, b) 
    if(arguments.length > 2) 
        var arg3 = arguments[3];
        //etc...
    

【讨论】:

【参考方案4】:

在多态中你可以使用不同的签名方法,在javascript中我们可以模拟多态检查函数参数的类型并执行某些任务。

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: \n'+arg;
  else if (arg.tagName && arg.tagName === 'INPUT')
    string = 'arg type Input: \n'+arg.value;
  
  if(arg1 && typeof arg1 === 'number')
    sqr = arg1*arg1;
    alert(string + ' and sqr = '+sqr);
  else 
    alert(string);
      

在JSFIDDLE查看这个例子

【讨论】:

【参考方案5】:

@abshik,

没有什么类似于 c# 或 java 的。 Javascript 的行为方式是这样的

function Test(arg1 ,arg2 , arg3, arg4)



调用该函数时可以通过以下方式调用

Test(arg1);
Test(arg1,arg2);
Test(arg1,arg2,arg3);
Test(arg1,arg2,arg3,arg4);

但顺序很重要,所以你可以通过上述方式发挥作用。

【讨论】:

你也可以不带参数或5+参数调用它。【参考方案6】:

问题是您试图重载一个函数,但 Javascript 不支持该函数。我认为您最好的选择是使用多态性。查看这篇文章了解更多详情:http://www.cyberminds.co.uk/blog/articles/polymorphism-in-javascript.aspx

【讨论】:

感谢@Joe_Francis 的回复。【参考方案7】:

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

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);

有趣的说明:您可以传入不在函数声明中的额外参数。执行console.logarguments,您会看到其中的所有内容。 arguments 是一个 object ,可以像 / 类型转换为 array 一样访问。

【讨论】:

是的,Jackson 对。我可以通过 arguments 对象访问所有参数吗?

以上是关于如何在 JavaScript/jQuery 中实现重载?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails - Javascript/jQuery 到 Haml

在JavaScript / jQuery中从列中获取所有值而不重复

在 HTML5 画布上工作时出现 JavaScript (JQuery) 问题

如何在Castle.Core中实现IProxyGenerationHook的类中实现Equals和GetHashCode的覆盖方法?

如何在android中实现svm模型?

如何在 laravel 中实现 vuetify?