在Javascript中伪造函数重载的最好方法是什么?
我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:
一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?
在Javascript中伪造函数重载的最好方法是什么?
我知道在Javascript中不可能像在其他语言中那样重载函数。 如果我需要一个函数有两个使用foo(x)和foo(x,y,z),这是最好的/首选的方式:
一开始就用不同的名字 使用可选参数,如y = y || 'default' 使用参数数量 检查参数类型 还是如何?
当前回答
最好的方法取决于函数和参数。你的每个选择在不同的情况下都是一个好主意。我通常按照以下顺序尝试这些方法,直到其中一个有效为止:
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.
其他回答
如果我需要一个函数与两个使用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语句。
你现在可以在ECMAScript 2018中进行函数重载,而无需填充,检查var长度/类型等,只需使用扩展语法。
function foo(var1, var2, opts){ // set default values for parameters const defaultOpts = { a: [1,2,3], b: true, c: 0.3289, d: "str", } // merge default and passed-in parameters // defaultOpts must go first! const mergedOpts = {...defaultOpts, ...opts}; // you can now refer to parameters like b as mergedOpts.b, // or just assign mergedOpts.b to b console.log(mergedOpts.a); console.log(mergedOpts.b); console.log(mergedOpts.c); console.log(mergedOpts.d); } // the parameters you passed in override the default ones // all JS types are supported: primitives, objects, arrays, functions, etc. let var1, var2="random var"; foo(var1, var2, {a: [1,2], d: "differentString"}); // parameter values inside foo: //a: [1,2] //b: true //c: 0.3289 //d: "differentString"
什么是扩展语法?
ECMAScript提案的Rest/Spread Properties(阶段4)将扩展属性添加到对象字面量中。它将自己的可枚举属性从提供的对象复制到新对象上。 更多关于mdn
注意:对象字面量中的扩展语法在Edge和IE中不起作用,这是一个实验特性。查看浏览器兼容性
JavaScript中没有真正的函数重载,因为它允许传递任意数量的任意类型的参数。你必须检查函数内部传递了多少参数以及它们的类型。
正确答案是JAVASCRIPT中没有重载。
检查/切换内部的功能不是过载。
超载的概念: 在某些编程语言中,函数重载或方法重载是用不同的实现创建多个同名方法的能力。对重载函数的调用将运行该函数的特定实现,适用于调用的上下文,允许一个函数调用根据上下文执行不同的任务。
例如,doTask()和doTask(object O)是重载方法。要调用后者,必须将对象作为参数传递,而前者不需要参数,并且使用空参数字段调用。一个常见的错误是将默认值赋给第二个方法中的对象,这将导致一个模糊的调用错误,因为编译器不知道使用两个方法中的哪一个。
https://en.wikipedia.org/wiki/Function_overloading
所有建议的实现都很棒,但说实话,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