JavaScript中的方法重载

我使用方法重载如下在我的Javascript代码。

function somefunction() { //1st function } function somefunction(a) { //2nd function } function somefunction(a,b) { //3rd function } somefunction(); // function call goes here 

我不明白的是,如果我调用somefunction() JavaScript应该调用第一个function,但问题是JavaScript实际上调用第三个function 。 这是为什么? 我怎样才能调用第一和第二function? 这是什么原因? 有没有一个正确的方法来实现JavaScript方法重载? 什么是行业标准?

JavaScript不支持方法重载(如在Java或类似),你的第三个函数覆盖以前的声明。

相反,它通过arguments对象支持可变参数。 你可以做

 function somefunction(a, b) { if (arguments.length == 0) { // a, b are undefined // 1st body } else if (arguments.length == 1) { // b is undefined // 2nd body } else if (arguments.length == 2) { // both have values // 3rd body } // else throw new SyntaxError? } 

你也可以检查typeof a == "undefined"等,这将允许调用somefunction(undefined) ,其中arguments.length1 。 这可能允许使用各种参数进行更简单的调用,例如,当您有可能的variables时。

你只是用每个新的声明擦除variablessomefunction

这相当于

  window.somefunction = function(... window.somefunction = function(... window.somefunction = function(... 

Javascript不提供方法重载。

正确的方法是:

  • 定义第三个函数并testing定义了哪些参数
  • 只传递一个包含参数的对象(这并不是真的不同,但更清洁)

JS将undefined的任何parameter passing给未提供。 如果你想要重载的东西,你需要做类似下面的代码:

 function someFunction(a, b) { if (typeof a === 'undefined') { // Do the 0-parameter logic } else if (typeof b === 'undefined') { // Do the 1-parameter logic } else { // Do the 2-parameter logic } } 

你不能在JavaScript中重载方法。 在JavaScript中,函数存储在variables中。 全局variables存储在窗口对象上。 每个对象具有相同的名称(独占密钥散列)只能有一个属性。

你可以做的是用最多的参数来定义定义,并检查有多less人通过。

 function Test(a, b, c) { if(typeof a == 'undefined') { a = 1; } if(typeof b == 'undefined') { b = "hi"; } if(typeof c == 'undefined') { c = Date.Now; } } 

现在,如果我调用Test(),它就像我调用Test(1, "hi", Date.Now)

在JavaScript中没有真正的函数重载,因为它允许传递任何types的任意数量的参数。 最好的做法是制作一个函数:myfunc(opt)

 { // with opt = {'arg1':'a1','arg2':2, etc}, then check your opt inside of the function } 

我试图开发一个优雅的解决scheme来解决这个问题。 你可以在这里find演示。 用法如下所示:

 var out = def({ 'int': function(a) { alert('Here is int '+a); }, 'float': function(a) { alert('Here is float '+a); }, 'string': function(a) { alert('Here is string '+a); }, 'int,string': function(a, b) { alert('Here is an int '+a+' and a string '+b); }, 'default': function(obj) { alert('Here is some other value '+ obj); } }); out('ten'); out(1); out(2, 'robot'); out(2.5); out(true); 

用来实现这个的方法:

 var def = function(functions, parent) { return function() { var types = []; var args = []; eachArg(arguments, function(i, elem) { args.push(elem); types.push(whatis(elem)); }); if(functions.hasOwnProperty(types.join())) { return functions[types.join()].apply(parent, args); } else { if (typeof functions === 'function') return functions.apply(parent, args); if (functions.hasOwnProperty('default')) return functions['default'].apply(parent, args); } }; }; var eachArg = function(args, fn) { var i = 0; while (args.hasOwnProperty(i)) { if(fn !== undefined) fn(i, args[i]); i++; } return i-1; }; var whatis = function(val) { if(val === undefined) return 'undefined'; if(val === null) return 'null'; var type = typeof val; if(type === 'object') { if(val.hasOwnProperty('length') && val.hasOwnProperty('push')) return 'array'; if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString')) return 'date'; if(val.hasOwnProperty('toExponential')) type = 'number'; if(val.hasOwnProperty('substring') && val.hasOwnProperty('length')) return 'string'; } if(type === 'number') { if(val.toString().indexOf('.') > 0) return 'float'; else return 'int'; } return type; }; 

我不明白的是,如果我调用somefunction()JavaScript应该调用第一个function,但问题是JavaScript实际上调用第三个function。

这是预期的行为。

这是为什么 ?

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

这是为什么 ? 我怎样才能调用第一和第二function? 这是什么原因?

我认为适合大部分情况的方式之一是遵循 –

可以说你有方法

 function foo(x) { } 

不是JavaScript中不可能的重载方法你可以定义一个新的方法

 fooNew(x,y,z) { } 

然后修改第一个function如下 –

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

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

有没有一个正确的方法来做的方法重载? 什么是行业标准?

没有这样的标准,或者是在JavaScript中进行方法重载的更为有效的方法。 一个人应该做最适合他们编程devise的东西。 我会说简单的开关参数长度与检查types,它不是未定义应该就足够了。

( 更多细节 )

JavaScript中不直接支持方法重载。 下面是一个例子,你可以如下所示实现一些非常类似的function:

 function overloadMethod(object, name, fn){ if(!object._overload){ object._overload = {}; } if(!object._overload[name]){ object._overload[name] = {}; } if(!object._overload[name][fn.length]){ object._overload[name][fn.length] = fn; } object[name] = function() { if(this._overload[name][arguments.length]) return this._overload[name][arguments.length].apply(this, arguments); }; } function Students(){ overloadMethod(this, "find", function(){ // Find a student by name }); overloadMethod(this, "find", function(first, last){ // Find a student by first and last name }); } var students = new Students(); students.find(); // Finds all students.find("Rahul"); // Finds students by name students.find("Rahul", "Mhatre"); // Finds users by first and last name 

来源: 来源

参数对象用于创build像概念一样的重载方法。

参数是只在函数执行上下文中可用的特殊types的对象。

arguments.length属性用于标识传递给函数的参数的个数。

您可以更好地使用第一类函数来创build伪造的方法重载。 完整的概念在我自己的网站上解释: JavaScript中的重载函数