Перегрузка метода в Javascript
Я использую перегрузку метода, как показано ниже в моем Javascript-коде.
function somefunction()
{
//1st function
}
function somefunction(a)
{
//2nd function
}
function somefunction(a,b)
{
//3rd function
}
somefunction(); // function call goes here
Я не понимаю, что если я называю somefunction()
, javascript должен вызывать 1-ю функцию, но проблема в том, что javascript фактически вызывает 3-ей функцию. Почему это? Как я могу назвать 1-ю и 2-ю функции? Что является причиной этого? Есть ли способ реализовать перегрузку метода в Javascript? Что такое отраслевой стандарт?
Ответы
Ответ 1
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
. Это может позволить более простой вызов с различными параметрами, например, когда у вас есть возможно-пустые переменные.
Ответ 2
Вы просто стираете переменную somefunction
с каждым новым объявлением.
Это эквивалентно
window.somefunction = function(...
window.somefunction = function(...
window.somefunction = function(...
Javascript не предлагает перегрузки методов.
Правильный способ:
- чтобы определить третью функцию и проверить, какие параметры определены
- передать только один объект, содержащий параметры (который не совсем другой, но более чистый).
Ответ 3
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
}
}
Ответ 4
Вы не можете перегружать методы в JavaScript. В javascript функции хранятся в переменных. Глобальные переменные хранятся в объекте окна. Вы можете иметь только одно свойство для одного объекта с одним и тем же именем (хэш исключающего ключа).
Что вы можете сделать, определяется определение с большинством параметров и проверяет, сколько их было передано.
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)
Ответ 5
В JavaScript нет реальной перегрузки функций, поскольку она позволяет передавать любое количество параметров любого типа. наилучшей практикой было бы сделать функцию
как:
MyFunc (вариант)
{
// with opt = {'arg1':'a1','arg2':2, etc}, then check your opt inside of the function
}
Ответ 6
Я попытался разработать элегантное решение этой проблемы, описанной здесь здесь. И здесь вы можете найти демо здесь. Использование выглядит следующим образом:
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;
};
Ответ 7
Что я не понимаю, так это то, что если я вызываю somefunction(), javascript должен вызывать первую функцию, но проблема в том, что javascript фактически вызывает третью функцию.
Это ожидаемое поведение.
Почему это так?
Проблема в том, что JavaScript НЕ поддерживает перегрузку методов. Таким образом, если он видит/анализирует две или более функций с одинаковыми именами, он просто учитывает последнюю определенную функцию и перезаписывает предыдущие.
Почему это? Как я могу вызвать 1-ю и 2-ю функцию? В чем причина этого?
Один из способов, который, на мой взгляд, подходит для большинства случаев, заключается в следующем -
Допустим, у вас есть метод
function foo(x)
{
}
Вместо перегрузки метода , что невозможно в javascript, вы можете определить новый метод
fooNew(x,y,z)
{
}
а затем измените первую функцию следующим образом -
function foo(x)
{
if(arguments.length==2)
{
return fooNew(arguments[0], arguments[1]);
}
}
Если у вас много таких перегруженных методов, рассмотрите возможность использования switch
, а не просто операторов if-else
.
Есть ли правильный способ сделать перегрузку метода? Какой отраслевой стандарт?
Не существует стандарта как такового или более проверенного метода для перегрузки методов в javascript. Нужно делать то, что лучше всего подходит для их программирования. Я бы сказал, достаточно простого переключения длины аргументов с проверкой типа, чтобы оно не было неопределенным.
Ответ 8
Объект arguments используется для создания метода перегрузки как концепция.
аргументы - это особый тип объекта, доступный только внутри контекста выполнения функций.
Свойство arguments.length используется для идентификации количества параметров, переданных в функцию.
Вы можете лучше использовать функции первого класса для создания перегрузки поддельных методов. Полная концепция объясняется на моем собственном сайте: Функции перегрузки в JavaScript
Ответ 9
Перегрузка метода напрямую не поддерживается в 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
источник: источник