nobr
@nobr
Front-end / Shadow DOM / Canvas

Как создать перегруженный конструктор класса в JS?

Вполне вероятно, что я пытаюсь сделать что-то, что противоречит концепции JS. Поэтому если пользоваться перегрузками неправильно, посоветуйте, пожалуйста, что нужно сделать в этом случае.


Сейчас я пишу простые классы-обёртки над функциями рисования фигур на canvas. Например, я хочу сделать удобнее рисование окружности, для этого можно пропустить несколько параметров (или добавить, в случае с другими классами).


В оригинале рисование цветного круга выглядит так:
context.arc(x, y, radius, startDegrees, endDegrees, counterClockwise);
context.fillStyle = '#FF0';
context.fill();



Я хочу сократить до:
var circle = new Circle(x, y, radius, '#FF0');


Но поскольку иногда нужно нарисовать дугу или сектор, то необходимо оставить весь функционал, для этого сделать перегрузку:
var circle = new Circle(x, y, radius, '#FF0', startDegrees, endDegrees, counterClockwise);



Вообщем, вопрос в том, как правильно создавать (или рекомендуется создавать) перегруженные интерфейсы, которые могут отличаться не только количеством параметров, но и типом данных.
  • Вопрос задан
  • 7168 просмотров
Пригласить эксперта
Ответы на вопрос 5
sdevalex
@sdevalex
В вашем случае просто пишите…
function Circle(x, y, radius, color, startDegrees, endDegrees, counterClockwise)
{
}
Если не передать нужное число параметров, то незадействованые станут undefined.

Если нужно передеавать разные в разном порядке, то передавайте объект options…
function Circle(options)
{
}

Пример…
new Circle({ radius: 10, x: 40, y: 30 });

На CoffeeScript ещё лучше:
new Circle radius: 10, x: 40, y: 30
Ответ написан
Stdit
@Stdit
А зачем вам объект «окружность»? Что вы с ним потом собираетесь делать, ради чего здесь он создаётся? Может проще написать просто какой-нибудь «хелпер»:
helpers.circle = function (context, x, y, radius, color) {
    context.arc(x, y, radius, startDegrees, endDegrees, counterClockwise);
    context.fillStyle = color;
    context.fill();
}

Ну или завести объект «рисовальщик», хранящий ссылку на графический контекст и настройки рисования, и имеющий необходимые методы (вроде приведённого выше) для работы с этим контекстом:
function Painter(context, defaultColor) {
    this.context = context;
    this.defaultColor = defaultColor;
    this.circle = function (x, y, r, color) {
        if (color === undefined) {
            color = this.defaultColor;
        } 
        this.context.arc(x, .... // code
    }
}

Это если вам нужно наследование. Объекты по-моему имеет смысл создавать только для реально существующих инстансов (спрайты, например, от которых наследуются игровые объекты и персонажи). Если окружность — это динамический объект, тогда можно уже думать и крутить, в зависимости от архитектуры графики, например так:
function Circle(x, y, r, color) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.color = color;
    this.render = function (context) {
        context.arc(this.x, ... 
    }
}
Ответ написан
@egorinsk
У вас очень странное (не)понимание ООП, писать в конструктор объекта код рисования — похоже на наркоманство. Вообще, писать в конструкторе сколько-нибудь сложный код — плохая идея. Если вы хотите нарисовать круг, сделайте метод drawCircle(...)

То. что вы спрашиваете в вопросе, называется не перегрузка функции (в яваскрипт нельзя делать такие вещи), а значения аргументов по умолчанию. Чтобы их сделать, используем тот факт, что непереданный аргумент имеет значение undefined:

function (arg1, arg2, arg3) {
arg2 = arg2 || 10; // значение по умолчанию
arg3 = arg3 || 20;


}

Как видите, получилось совсем не сложно!
Ответ написан
Shuhrat
@Shuhrat
У Джона Резига была статья, вот только без проверки типа данных
Ответ написан
Комментировать
Stdit
@Stdit
[мимо]
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
17 апр. 2024, в 00:48
35000 руб./за проект
17 апр. 2024, в 00:13
800 руб./за проект
17 апр. 2024, в 00:06
240000 руб./за проект