Javascript 中的方法重载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12694588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Method overloading in Javascript
提问by Techie
I use method overloading as below in my Javascript code.
我在我的 Javascript 代码中使用如下方法重载。
function somefunction()
{
//1st function
}
function somefunction(a)
{
//2nd function
}
function somefunction(a,b)
{
//3rd function
}
somefunction(); // function call goes here
What I don't understand is if I call the somefunction()
javascript should call the 1st function but the problem is javascript actually calls the 3rd function. Why is that? How can I call the 1st and 2nd function ? What is the reason for this? Is there a proper way to implement method overloading in Javascript? What's the industry standard?
我不明白的是,如果我调用somefunction()
javascript 应该调用第一个函数,但问题是 javascript 实际上调用了第三个函数。这是为什么?如何调用第一个和第二个函数?这是什么原因?是否有正确的方法在 Javascript 中实现方法重载?行业标准是什么?
回答by Bergi
JavaScript does not support method overloading (as in Java or similiar), your third function overwrites the previous declarations.
JavaScript 不支持方法重载(如在 Java 或类似版本中),您的第三个函数会覆盖之前的声明。
Instead, it supports variable arguments via the arguments
object. You could do
相反,它通过arguments
object支持可变参数。你可以做
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?
}
You also could just check for typeof a == "undefined"
etc, this would allow calling somefunction(undefined)
, where arguments.length
is 1
. This might allow easer calling with various parameters, e.g. when you have possibly-empty variables.
您也可以只检查typeof a == "undefined"
等,这将允许调用somefunction(undefined)
, where arguments.length
is 1
。这可能允许使用各种参数更轻松地调用,例如,当您有可能为空的变量时。
回答by carlosfigueira
JS will pass undefined
to any parameters which are not provided. If you want something like overloading, you'll need to do something similar to the code below:
JS 将传递undefined
给任何未提供的参数。如果你想要重载之类的东西,你需要做一些类似于下面的代码:
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
}
}
回答by Denys Séguret
You're just erasing the variable somefunction
with each new declaration.
您只是somefunction
使用每个新声明擦除变量。
This is equivalent to
这相当于
window.somefunction = function(...
window.somefunction = function(...
window.somefunction = function(...
Javascript doesn't offer method overloading.
Javascript 不提供方法重载。
The proper way is either :
正确的方法是:
- to define the third function and to test what parameters are defined
- to pass only one object containing the parameters (which isn't really different but is cleaner)
- 定义第三个函数并测试定义了哪些参数
- 只传递一个包含参数的对象(这并没有真正不同,但更清晰)
回答by Sheridan Bulger
You can't overload methods in JavaScript. In javascript, functions are stored in variables. Global variables are stored on the window object. You can only have one property per object with the same name (exclusive-key hash).
你不能在 JavaScript 中重载方法。在javascript中,函数存储在变量中。全局变量存储在 window 对象上。每个对象只能有一个同名的属性(独占键哈希)。
What you can do, is define the definition with the most parameters and check to see how many were passed in.
您可以做的是定义具有最多参数的定义,并检查传入的参数数量。
function Test(a, b, c)
{
if(typeof a == 'undefined')
{
a = 1;
}
if(typeof b == 'undefined')
{
b = "hi";
}
if(typeof c == 'undefined')
{
c = Date.Now;
}
}
Now if I call Test(), it'll act as if I called Test(1, "hi", Date.Now)
现在,如果我调用 Test(),它将表现得好像我调用了 Test(1, "hi", Date.Now)
回答by Frenchi In LA
There is no real function overloading in JavaScript since it allows to pass any number of parameters of any type. the best practice would be to make a function like: myfunc(opt)
JavaScript 中没有真正的函数重载,因为它允许传递任意数量的任意类型的参数。最好的做法是创建一个函数,如:myfunc(opt)
{
// with opt = {'arg1':'a1','arg2':2, etc}, then check your opt inside of the function
}
回答by stamat
I tried to develop an elegant solution to this problem described here. And you can find the demo here. The usage looks like this:
我试图为这里描述的这个问题开发一个优雅的解决方案。您可以在此处找到演示。用法如下所示:
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);
The methods used to achieve this:
用于实现此目的的方法:
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;
};
回答by Aniket Thakur
What I don't understand is if I call the somefunction() javascript should call the 1st function but the problem is javascript actually calls the 3rd function.
我不明白的是,如果我调用 somefunction() javascript 应该调用第一个函数,但问题是 javascript 实际上调用了第三个函数。
That is expected behavior.
这是预期的行为。
Why is that ?
这是为什么 ?
The issue is that JavaScript does NOT natively support method overloading. So, if it sees/parses two or more functions with a same names it'll just consider the last defined function and overwrite the previous ones.
问题是 JavaScript 本身不支持方法重载。因此,如果它看到/解析两个或多个具有相同名称的函数,它只会考虑最后定义的函数并覆盖之前的函数。
Why is that ? How can I call the 1st and 2nd function ? What is the reason for this?
这是为什么 ?如何调用第一个和第二个函数?这是什么原因?
One of the way I think is suitable for most of the case is follows -
我认为适合大多数情况的方法之一如下 -
Lets say you have method
假设你有方法
function foo(x)
{
}
Instead of overloading method which is not possible in javascriptyou can define a new method
您可以定义一个新方法,而不是重载在 javascript 中不可能的方法
fooNew(x,y,z)
{
}
and then modify the 1st function as follows -
然后修改第一个函数如下 -
function foo(x)
{
if(arguments.length==2)
{
return fooNew(arguments[0], arguments[1]);
}
}
If you have many such overloaded method consider using switch
than just if-else
statements.
如果您有许多这样的重载方法,请考虑使用switch
而不仅仅是if-else
语句。
Is there a proper way to do the method overloading ? What's the industry standard ?
有没有正确的方法来进行方法重载?什么是行业标准?
There is no standard as such or an more proven method to do method overloading in javascript. One should do what best suits their programming design. I would say simple switch on arguments length with checking type that it is not undefined should suffice.
没有这样的标准或更成熟的方法来在 javascript 中进行方法重载。人们应该做最适合他们的编程设计的事情。我会说简单地打开参数长度并检查它不是未定义的类型就足够了。
回答by Bear Nithi
argumentsobject are used to create a method overloading like concept.
arguments对象用于创建类似概念的方法重载。
argumentsis a special type of object that's only available inside the functions execution context.
arguments是一种特殊类型的对象,只能在函数执行上下文中使用。
arguments.lengthproperty is used to identify the number of parameters passed into the function.
arguments.length属性用于标识传递给函数的参数数量。
You can make the better use of first class functions to create fake method overloading. The full concept is explained on my own website: Overload Functions in JavaScript
您可以更好地利用一流的函数来创建假方法重载。完整的概念在我自己的网站上进行了解释:JavaScript 中的重载函数
回答by mamosek
Method overloading is not directly supported in JavaScript. Here is an example how you can achieve something very much like it as shown below:
JavaScript 不直接支持方法重载。这是一个示例,您可以如何实现与它非常相似的内容,如下所示:
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
source: source
来源:来源
回答by jbe90
If you use classes you create two different classes which have the same method with different parameters. Then you can use spread operator along with dependency injection to mimic the overloading behavior.
如果您使用类,则会创建两个不同的类,它们具有相同的方法和不同的参数。然后你可以使用扩展运算符和依赖注入来模拟重载行为。
class Foo{
method(){
console.log('hello from method foo')
}
}
class Bar{
method(name){
console.log(`hello from method bar. Name is ${name}`)
}
}
function MimicOverload(obj, options){
obj.method(...options)
}
const obj1 = new Foo()
const obj2 = new Bar()
MimicOverload(obj1,[])
MimicOverload(obj2,['overloaded'])