【问题标题】:How can implement overloading in JavaScript/jQuery?如何在 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;'
  • 阅读这个问题的答案:stackoverflow.com/questions/456177/…
  • @lbu - 转义引号,虽然在这种情况下没有必要,但实际上并没有伤害它吗?我会更担心右括号和返回之间没有分号。
  • 我只想指出,作为搜索的一部分阅读此问题的人们 Abhishek 所描述的称为方法重载,不是多态性。多态性是遵守特定接口或契约的能力。 Javascript 是一种鸭式语言,具有隐含的多态性。
  • @Randolpho 感谢您的描述。

标签: javascript oop dom-events


【解决方案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 对象访问所有参数吗?
          猜你喜欢
          • 1970-01-01
          • 2014-10-15
          • 1970-01-01
          • 2012-07-16
          • 2010-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多