"перегрузка метода" в JavaScript - PullRequest
3 голосов
/ 18 февраля 2009

Итак, я признаю, что я новичок в javascript и что я пришел из C. + («Привет, я Боб, я пользователь статического языка на основе классов», chorus"Привет, Боб!").

Я считаю, что часто пишу такие функции, как:

function someFunc()
{
    if (arguments.length === 0 ){
       ...
    } else {
       ...
    }
}

(где может быть три таких случая). Или, в качестве альтернативы, я пишу разницу в названии:

function someFuncDefault() { ... };
function someFuncRealArg(theArg) { ... };

(Заменить "RealArg" на семантически содержательную фразу).

Есть ли лучший образец для такого рода вещей?

Ответы [ 8 ]

5 голосов
/ 18 февраля 2009

Посмотрите на этот пост .

3 голосов
/ 18 февраля 2009

Я не знаю, что я сделал бы это таким образом, но кажется, что это может сделать ваш код мягко менее управляемым:

function someFunc() {
    switch (arguments.length) {
        case 0: noArgs();
        case 1: oneArg(arguments[0]);
        case 2: twoArgs(arguments[0], arguments[1]);
    }
    function noArgs() {
        // ...
    }
    function oneArg(a) {
        // ...
    }
    function twoArgs(a, b) {
        // ...
    }
}

Другой пример:

function someFunc(a, b) {
    if ('string' == typeof a) {
        // ...
    } else if ('number' == typeof a) {
        // ...
    }
}

И, конечно, вы, вероятно, можете создать нечто совершенно неуправляемое, комбинируя оба примера (используя условия для определения поведения на основе количества аргументов и типов аргументов).

1 голос
/ 18 февраля 2009

Это перегрузка, а не переопределение нет?

Javascript имеет слабую типизацию, поэтому отсутствуют сигнатуры методов и встроенная поддержка. Я рекомендую передать расширяемый объект в качестве единственного аргумента. Проверяйте и обрабатывайте наличие свойств объекта param по своему усмотрению.

Какое преимущество это имеет перед аргументами? Что ж, он позволяет вам четко указывать свои намерения там, где вы вызываете, и недвусмысленно понимать значение arg1 и arg2, куда вы получаете, и позволяет абстрагироваться от пользовательского класса объектов данных, до которого вы можете расширить функциональность.

function someFunc(params)
{
  var x = params.x || defaultX;
  var y = params.y || defaultY;

  //businesslogic
}

someFunc({x:'foo',y:'bar'});

someFunc({y:'baz'});
1 голос
/ 18 февраля 2009

В Javascript все аргументы являются необязательными.

Вы можете попробовать что-то вроде:

Редактировать (лучший метод, который не ломается для значений, чья «правдивость» ложна):

function bar(arg1, arg2) {
  if(arg1 === undefined) { set default }
  if(arg2 === undefined) { set default }
  //do stuff here
}

Старый метод, который ломается для значений фальси:

function foo(arg1, arg2) {
  if(!arg1) { set default }
  if(!arg2) { set default }
  //do stuff here
}

Прекрасным местом для начала является javascript лекций Дугласа Крокфорда: http://video.yahoo.com/search/?p=javascript

0 голосов
/ 03 апреля 2013

bob.js :

предлагает немного более полный механизм перегрузки.
var notify = new bob.fn.overloadFunction([ 
    { 
        condition: function(msg) { return bob.utils.isString(msg); }, 
        overload: function(msg) { 
            console.log(msg); 
        } 
    }, 
    { 
        condition: function(bSayHello) { return bob.utils.isBoolean(bSayHello); }, 
        overload: function(bSayHello, msg) { 
            msg = bSayHello ? 'Hello: ' + msg : msg; 
            console.log(msg); 
        } 
    } 
]); 

Вызов перегруженной функции:

notify('Simple sentence.'); 
// Output: 
// Simple sentence. 
notify(true, 'Greeting sentence.'); 
// Output: 
// Hello: Greeting sentence. 
notify(123); 
// JavaScript Error: 
// "No matching overload found." 
0 голосов
/ 18 февраля 2009

Лично я предпочитаю написать наиболее сложную функцию, которая будет выполняться, а затем задокументировать ее в комментариях, чтобы другие знали, что они не должны отправлять все аргументы.

//concat(str1, str2 [,str3 [,str4 [,str5]]])
function concat(str1, str2, str3, str4, str5) {
    var str = str1 + str2;
    if(str3 != undefined)
        str += str3;
    if(str4 != undefined)
        str += str4;
    if(str5 != undefined)
        str += str5;
    return str;
}

Я также обнаружил ситуации, в которых порядок аргументов имел бы значение для нормальной функции, но иногда мне хотелось бы отправлять аргументы отдельно (т.е. я хотел бы отправлять str3 и str5, но не str4). Для этого я использую объект и проверяю известные свойства

//concat({str1:string, str2:string, str3:string, str4:string, str5:string})
//str3, str4, and str5 are optional
function concat(strngs) {
    var str = strngs.str1 + strngs.str2;
    if(strngs.str3 != undefined)
        str += strngs.str3;
    if(strngs.str4 != undefined)
        str += strngs.str4;
    if(strngs.str5 != undefined)
        str += strngs.str5;
    return str;
}
0 голосов
/ 18 февраля 2009

Все подошли близко, я думаю, что реальная проблема в том, что в JavaScript вы не должны изменять поведение в зависимости от передаваемых параметров.

Поскольку JavaScript делает все параметры необязательными, вы можете придерживаться краткого метода использования этого соглашения:

function foo(bar, baz) {
    bar = bar || defaultBar;
    baz = baz || defaultBaz;
    .
    .
    .
}
0 голосов
/ 18 февраля 2009

Javascript позволяет вам по-настоящему лениться (не так лениво, как Python, но довольно лениво).

function someFunc(arg1, arg2)
{
  if(typeof(arg1) == "undefined") {
    arg1 = default;
  }
  ... 
}

Так что вам не нужно перегружать. Javascript не будет кричать на вас за неправильное количество параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...