Обновить
22
0
Егор Балышев@furagu

Пользователь

Отправить сообщение
Это по сути модификация стандартного бойлерплейта вида

function (required, optional, callback) {
    if (typeof optional === 'function') {
        callback = optional
        optional = 'default value'
    }
    // ...
}

Только модификация еще и мутноватая. Не сразу понятно, правильно ли там все работает из-за того, что используется состояние массива args. Уж лучше переприсваивать параметры.

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

Весь сыр-бор ведь из-за функций, принимающих callback, верно? Так значит и тестировать нужно вызов с callback'ом. А то что вы протестировали — манипуляция массивами против присваивания переменных.

Тестировал я функции вот такого вида:

var add = function (a, b, options, callback) {
    if (typeof options === 'function') {
        callback = options
        options = {}
    }
    var sum = a + b
    return callback(null, sum)
}

В процессе написания корректного тест-кейса я манипуляции массивами ускорил где-то в три с половиной раза.
Получилось вот что: Arguments normalization test

В Хроме этот тест выдает 2 047 549 Ops/sec VS 15 220 768 Ops/sec. Разница в восемь раз, а не в тысячу.
Насколько это критично? Зависит уже от абсолютного значения разницы.

А абсолютные цифры таковы: накладные расходы при однократном вызове декорированной функции составляют 0,4 микросекунды. Эта задержка не будет иметь никакого значения, если декорировать, например, jQuery.get или fs.readFile. До тех пор, конечно, пока вы не начнете вызывать их сотни тысяч раз в секунду.

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

«Premature optimization is the root of all evil», помните?
В статье речь не об альтернативе нормализации, а о том, как эту нормализацию делать. «Очевидный сдвиг» аргументов в теле функции меня не устраивает, я рассказал почему.
Хороший подход для интерфейсных штук, когда callback'ов много и вся инфраструктура вокруг вашего кода работает по таким же соглашениям. Когда таких соглашений нет — придется самому все превращать в объекты. И с функциональными штуками вроде map и filter комбинируется только через промежуточные функции.
Зато каждому, кто будет потом этот код поддерживать, придется учить «язык определения параметров».

С разным количеством аргументов код чище. Сравните:

fs.readFile(filename, callback)

и

fs.readFile({filename: filename}, callback)
А мне кажется, что callback в конце дает больше преимуществ.

1. Это снижает шансы не заметить дополнительные параметры при использовании анонимных callback'ов.

Параметр data видно сразу:
$.get(url, data, function (response) {
// …
})


Параметр data видно уже после того, как прочитал тело callback'а:
$.get(url, function (response) {
// …
}, data)


2. Это удобно для частичного применения функций. В варианте с callback'ом в середине зафиксировать получится только аргументы до него.

3. Ну и наконец, это стандарт для Node.js и большого количества библиотек (тот же async, например).
Пожалуй, цикл в примере я выбрал не очень удачно.

Представьте ситуацию, когда цикл неявный, и переменной i нет.
Или другую: нужно раскрасить не все юниты, а только наземные.

var next_color = revolver(['red', 'green', 'blue']);

for (var i = 0; i < units.length; i += 1) {
    if (units[i].type === LAND_UNIT) {
        units[i].color = next_color();
    }
}
Да, я знаю что по геймплейным фишкам моему приложению до классических Space Invaders еще далеко. Просто мне хотелось сделать динамичную версию, с красивыми взрывами, на что ушло достаточно кода :) Что касается движения от одного края экрана до другого — наверное можно было бы вместить, но времени уже не оставалось.
А усложнение от этапа к этапу есть и у меня — постепенно растет скорость снижения захватчиков (разве что очень медленно) и сами они становятся агрессивнее — чаще стреляют.
Я собирался добавить несколько жизней, но потом передумал: с одной жизнью игра держит в большем напряжении :)
My fault :( В последний момент над игровым полем добавил span для отображения очков а само поле уменьшить забыл.
Да, они специально так движутся — мне хотелось динамики, и я отступил от канона.
А что конкретно стоит рассказать о конкурсе? Все же просто было — увидел пост habrahabr.ru/blogs/webdev/100548/ и решил, что такой конкурс я пропустить не могу :)
Что касается процесса разработки — ок, считаю ваш голос как еще плюс один к желающим узнать подробнее.
Способа начать игру заново нет — код не поместился в 10 килобайт. Синие снаряды это да, монитор на котором я отлаживал был излишне ярким и все хорошо было видно. Мне коллеги позже тоже жаловались на «синих тварей», стреляющих невидимыми снарядами, но было уже поздно, время размещения приложений закончилось.
Спасибо. Сначала я не планировал стрельбу очередью, но потом понял — нужно больше экшена :)

Информация

В рейтинге
Не участвует
Откуда
Красноярск, Красноярский край, Россия
Зарегистрирован
Активность