在Javascript中伪造函数重载的最好方法是什么?

我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:

一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?


当前回答

我们用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);
    }
  )

};

其他回答

你可以使用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);
  };
}

对于函数重载,可以这样做。

function addCSS(el, prop, val) {
  return {
    2: function() {
      // when two arguments are set
      // now prop is an oject
      for (var i in prop) {
          el.style[i] = prop[i];
      }
    },
    3: function() {
      // when three arguments are set
      el.style[prop] = val;
    }
    }[arguments.length]();
}
// usage
var el = document.getElementById("demo");
addCSS(el, "color", "blue");
addCSS(el, {
    "backgroundColor": "black",
  "padding": "10px"
});

多年来,我一直在使用这个函数来美化我的重载:

function overload(){
  const fs = arguments, fallback = fs[fs.length - 1];
  return function(){
    const f = fs[arguments.length] || (arguments.length >= fs.length ? fallback : null);
    return f.apply(this, arguments);
  }
}

型:

function curry1(f){
  return curry2(f, f.length);
}

function curry2(f, minimum){
  return function(...applied){
    if (applied.length >= minimum) {
      return f.apply(this, applied);
    } else {
      return curry2(function(...args){
        return f.apply(this, applied.concat(args));
      }, minimum - applied.length);
    }
  }
}

export const curry = overload(null, curry1, curry2);

看看jQuery的off方法:

  function off( types, selector, fn ) {
    var handleObj, type;
    if ( types && types.preventDefault && types.handleObj ) {

        // ( event )  dispatched jQuery.Event
        handleObj = types.handleObj;
        jQuery( types.delegateTarget ).off(
            handleObj.namespace ?
                handleObj.origType + "." + handleObj.namespace :
                handleObj.origType,
            handleObj.selector,
            handleObj.handler
        );
        return this;
    }
    if ( typeof types === "object" ) {

        // ( types-object [, selector] )
        for ( type in types ) {
            this.off( type, selector, types[ type ] );
        }
        return this;
    }
    if ( selector === false || typeof selector === "function" ) {

        // ( types [, fn] )
        fn = selector;
        selector = undefined;
    }
    if ( fn === false ) {
        fn = returnFalse;
    }
    return this.each( function() {
        jQuery.event.remove( this, types, fn, selector );
    } );
  }

许多重载函数在优化性能时几乎不可读。你必须破译函数的头部。这可能比使用我提供的重载函数更快;但是,从人的角度来看,它在识别调用了哪个重载方面要慢一些。

正确答案是JAVASCRIPT中没有重载。

检查/切换内部的功能不是过载。

超载的概念: 在某些编程语言中,函数重载或方法重载是用不同的实现创建多个同名方法的能力。对重载函数的调用将运行该函数的特定实现,适用于调用的上下文,允许一个函数调用根据上下文执行不同的任务。

例如,doTask()和doTask(object O)是重载方法。要调用后者,必须将对象作为参数传递,而前者不需要参数,并且使用空参数字段调用。一个常见的错误是将默认值赋给第二个方法中的对象,这将导致一个模糊的调用错误,因为编译器不知道使用两个方法中的哪一个。

https://en.wikipedia.org/wiki/Function_overloading

所有建议的实现都很棒,但说实话,JavaScript没有原生实现。

JavaScript中没有真正的函数重载,因为它允许传递任意数量的任意类型的参数。你必须检查函数内部传递了多少参数以及它们的类型。