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.length
是1
。 这可能允许使用各种参数进行更简单的调用,例如,当您有可能的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中的重载函数