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

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

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


当前回答

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

得益于此,您可以轻松地定义非常灵活的方法签名,恕我直言,这比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中没有真正的函数重载,因为它允许传递任意数量的任意类型的参数。你必须检查函数内部传递了多少参数以及它们的类型。

我正在做一个库,提供类的代码功能,Javascript,目前它支持构造函数,继承,方法重载参数的数量和参数的类型,混合,静态属性和单例。

请参阅使用该库的方法重载示例:

eutsiv.define('My.Class', {
    constructor: function() {
        this.y = 2;
    },
    x: 3,
    sum: function() {
        return this.x + this.y;
    },
    overloads: {
        value: [
            function() { return this.x + ', ' + this.y },
            function(p1) { this.x = p1; },
            function(p1, p2) { this.x = p1; this.y = p2; }  // will set x and y
        ]
    }
});

var test = new My.Class({ x: 5 });   // create the object
test.value();                        // will return '5, 2'
test.sum();                          // will return 7
test.value(13);                      // will set x to 13
test.value();                        // will return '13, 2'
test.sum();                          // will return 15
test.value(10, 20);                  // will set x to 10 and y to 20
test.value();                        // will return '10, 20'
test.sum();                          // will return 30

欢迎任何反馈,bug修复,文档和测试改进!

https://github.com/eutsiv/eutsiv.js

所以我真的很喜欢这种做事的方式,这是我在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语句,如果您开始编写复杂的代码,它将变得难以阅读(接受的答案将导致这种结果)。

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

另一种方法是使用特殊的变量:arguments,这是一个实现:

function sum() {
    var x = 0;
    for (var i = 0; i < arguments.length; ++i) {
        x += arguments[i];
    }
    return x;
}

所以你可以修改这段代码:

function sum(){
    var s = 0;
    if (typeof arguments[0] !== "undefined") s += arguments[0];
.
.
.
    return s;
}

如果我需要一个函数与两个使用foo(x)和foo(x,y,z)哪种是最好的/首选的方式?

问题是JavaScript本身不支持方法重载。因此,如果它看到/解析了两个或多个同名的函数,它只会考虑最后定义的函数,并覆盖之前的函数。

我认为适用于大多数情况的一种方法是

假设你有方法

function foo(x)
{
} 

而不是重载方法,这在javascript中是不可能的,你可以定义一个新的方法

fooNew(x,y,z)
{
}

然后将第一个函数修改为-

function foo(arguments)
{
  if(arguments.length==2)
  {
     return fooNew(arguments[0],  arguments[1]);
  }
} 

如果你有很多这样的重载方法,考虑使用switch而不是If -else语句。