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

};

其他回答

因为这篇文章已经包含了很多不同的解决方案,所以我想再发一个。

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忍者的秘密中发现的

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将重载函数添加到任何对象。对我来说,这段代码中的主要困惑是fn的使用。Length ==参数。长度,这是因为fn。长度是预期参数的数量,而参数。长度是函数实际调用的参数的数量。匿名函数没有参数的原因是你可以在javascript中传入任意数量的参数,并且语言是宽容的。

我喜欢这个,因为你可以在任何地方使用它-只需创建这个函数,并在任何你想要的代码库中简单地使用这个方法。

它还避免了一个大得离谱的if/switch语句,如果您开始编写复杂的代码,它将变得难以阅读(接受的答案将导致这种结果)。

在缺点方面,我想代码一开始有点晦涩……但我不确定其他人?

不是每个人都知道可以在函数签名中直接进行解构赋值。

得益于此,您可以轻松地定义非常灵活的方法签名,恕我直言,这比Java方法重载更优越。

例子:

const myFunction = (({a, b, c}) => {
    console.log(a, b, c);
});

myFunction({a: 1, b: 2});
myFunction({a: 1, b: 2, c: 3});

您甚至不需要考虑参数的顺序,并且调用语句和目标方法签名之间具有命名一致性。

你也可以指定默认值:

const myFunction = (({a = 1, b = 2, c} = {}) => {
    console.log(a, b, c);
});

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

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

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

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

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

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

最好的方法取决于函数和参数。你的每个选择在不同的情况下都是一个好主意。我通常按照以下顺序尝试这些方法,直到其中一个有效为止:

Using optional arguments like y = y || 'default'. This is convenient if you can do it, but it may not always work practically, e.g. when 0/null/undefined would be a valid argument. Using number of arguments. Similar to the last option but may work when #1 doesn't work. Checking types of arguments. This can work in some cases where the number of arguments is the same. If you can't reliably determine the types, you may need to use different names. Using different names in the first place. You may need to do this if the other options won't work, aren't practical, or for consistency with other related functions.