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

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

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


当前回答

在JS中没有实际的重载,无论如何我们仍然可以用几种方式模拟方法重载:

方法# 1: 使用对象

function test(x,options){
  if("a" in options)doSomething();
  else if("b" in options)doSomethingElse();
}
test("ok",{a:1});
test("ok",{b:"string"});

方法# 2: 使用rest (spread)参数

function test(x,...p){
 if(p[2])console.log("3 params passed"); //or if(typeof p[2]=="string")
else if (p[1])console.log("2 params passed");
else console.log("1 param passed");
}

方法# 3: 使用未定义的

function test(x, y, z){
 if(typeof(z)=="undefined")doSomething();
}

方法# 4: 类型检查

function test(x){
 if(typeof(x)=="string")console.log("a string passed")
 else ...
}

其他回答

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

截至2017年7月,以下是常见的技术。注意,我们还可以在函数中执行类型检查。

function f(...rest){   // rest is an array
   console.log(rest.length);
   for (v of rest) if (typeof(v)=="number")console.log(v);
}
f(1,2,3);  // 3 1 2 3

我正在做一个库,提供类的代码功能,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

看看这个。它很酷。 http://ejohn.org/blog/javascript-method-overloading/ 技巧Javascript,让你做这样的调用:

var users = new Users();
users.find(); // Finds all
users.find("John"); // Finds users by name
users.find("John", "Resig"); // Finds users by first and last name

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

得益于此,您可以轻松地定义非常灵活的方法签名,恕我直言,这比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);
});