- PVSM.RU - https://www.pvsm.ru -
Автор статьи, перевод которой мы сегодня публикуем, решил поделиться с читателями семью рекомендациями по JavaScript. Эти рекомендации, как хочется надеяться автору, помогут писать более надёжные программы.
Если кто не знает, фабричная функция — это обычная функция (не класс и не конструктор), которая возвращает объекты. Эта простая концепция позволяет нам воспользоваться полезными возможностями JavaScript для создания мощных и надёжных приложений.
Важно знать о том, что фабричная функция вызывается без использования ключевого слова new. Если вызвать её с данным ключевым словом, она перестанет вести себя так, как должна.
Фабричные функции могут быть использованы для упрощения создания экземпляров объекта без необходимости связываться с классами или с ключевым словом new.
Суть фабричных функций в том, что их рассматривают как самые обыкновенные функции. Это означает, что они могут использоваться для конструирования объектов, других функций и даже промисов. То есть, такие функции можно сочетать и комбинировать для создания более мощных фабричных функций, которые, в свою очередь, тоже можно, объединяя с другими функциями или объектами, применять для создания ещё более продвинутых фабричных функций. Фабричные функции открывают перед программистом безграничные возможности.
Если учесть вышесказанное и совместить использование фабричных функций с рекомендованными подходами по написанию кода, эти функции способны стать мощнейшими и удобнейшими инструментами.
Вот простой пример фабричной функции:
function createFrog(name) {
const children = []
return {
addChild(frog) {
children.push(frog)
},
}
}
const mikeTheFrog = createFrog('mike')
Если некоторое время пользоваться фабричными функциями, можно прийти к пониманию того, что, в сравнении с их конкурентами в виде функций-конструкторов, фабричные функции способны повысить уровень повторного использования кода. В результате программисту приходится писать меньше кода. Фабричные функции облегчают рефакторинг, так как они способны возвращать произвольные объекты, и упрощают работу над кодовой базой.
Если вы только недавно начали осваивать JavaScript, то работа с прототипом объекта может показаться вам чем-то новым. Так, в самом начале, было и со мной.
Учитывайте то, что эта методика не подходит для классов. Классы, без дополнительных усилий со стороны программиста, самостоятельно сохраняют методы в своих прототипах.
Вот пример функции-конструктора:
function Frog(name, gender) {
this.name = name
this.gender = gender
}
Frog.prototype.leap = function(feet) {
console.log(`Leaping ${feet}ft into the air`)
}
Зачем пользоваться конструкцией Frog.prototype.leap вместо того, чтобы просто записать метод leap в создаваемый конструктором объект? Например — так:
function Frog(name, gender) {
this.name = name
this.gender = gender
this.leap = function(feet) {
console.log(`Leaping ${feet}ft into the air`)
}
}
Дело в том, что если метод прикрепляется напрямую к свойству конструктора prototype — это значит, что данный метод будут совместно использовать все экземпляры объекта, созданные конструктором.
Другими словами, если опираться на предыдущий пример, в котором используется this.leap, то окажется, что при создании нескольких экземпляров объекта Frog у каждого из них будет собственный метод leap. То есть — будет создано несколько копий этого метода. В данном случае это говорит о нерациональном использовании системных ресурсов, так как во всех этих объектах будет присутствовать копия одного и того же метода, который везде ведёт себя одинаково. Создавать копии такого метода в каждом из экземпляров объекта не нужно.
В итоге это приведёт к ухудшению производительности программы. А ведь этого несложно избежать. Надо отметить, что свойства this.name и this.gender должны быть объявлены именно в таком виде, так как они должны принадлежать конкретному объекту. Если провести аналогию с настоящими лягушками, виртуальное представление которых описано с помощью конструктора Frog, то окажется, что у лягушек могут быть собственные имена, лягушки имеют разный пол. Как результат — для хранения в каждом из объектов уникальных сведений о лягушках свойства объектов имеет смысл объявлять так, чтобы они использовались бы именно на уровне экземпляров объектов.
Вот [2] пример использования этой методики в популярном пакете request [3].
Свойство .type, которое, по неофициальному соглашению, часто добавляют к объектам, нашло в наши дни чрезвычайно широкое применение. Если вы пишете React-приложения, то вы, возможно, сталкиваетесь с этим свойством постоянно. Особенно — если применяете Redux [4].
Использование подобного подхода очень хорошо показывает себя в процессе разработки, так как он, кроме прочего, позволяет создавать самодокументирующийся код:
function createSpecies(type, name, gender) {
if (type === 'frog') {
return createFrog(name, gender)
} else if (type === 'human') {
return createHuman(name, gender)
} else if (type == undefined) {
throw new Error('Cannot create a species with an unknown type')
}
}
const myNewFrog = createSpecies('frog', 'sally', 'female')
TypeScript [5] получил широкое распространение в JavaScript-сообществе благодаря тому, что этот язык даёт в руки программиста мощное средство для безопасной работы с типами, а также позволяет выявлять ошибки ещё до того, как они проявятся в работающем коде.
Применение TypeScript позволяет находить потенциальные ошибки на этапе компиляции кода, ещё до того, как код будет запущен. Если в коде что-то не так — при его компиляции будет выведено соответствующее уведомление.
Но типобезопасность и раннее выявление ошибок — это далеко не полный список причин применения TypeScript в любых ситуациях. Одной из замечательных особенностей TypeScript является то, что этот язык позволяет пользоваться новыми возможностями JavaScript ещё до того, как их реализация появится в основных браузерах. Дело в том, что TypeScript-код компилируется в JavaScript-код, поддерживаемый как современными, так и не самыми новыми браузерами.
Если вы работаете над проектом и серьёзно настроены на эту работу, то вам практически необходимо писать тесты. Это позволит сделать код более предсказуемым, позволит сделать его менее подверженным ошибкам. Это даст более высокий уровень уверенности в качестве кода при внесении в него изменений. Другими словами, если вы хотите, чтобы ваш код выдержал бы проверку временем, нет лучшего способа подготовки кода к этой проверке, чем написание тестов. Чем больше тестов имеется в вашем проекте — тем больше уверенности в коде у вас будет при развёртывании его в продакшне.
Если бы нужно было выделить лишь одну, самую важную, положительную черту тестов, что бы это было? Полагаю, это тот факт, что тесты помогают находить ошибки до их попадания в работающую программу. Какому программисту не хотелось бы обладать такой возможностью? Я, совершенно точно, от такого не отказался бы. Именно поэтому я и пишу модульные тесты для своих проектов.
Если вы только собираетесь приступить к созданию тестов для своего проекта — знайте о том, что в наши дни существует масса инструментов и фреймворков для организации тестирования кода. Вот [6] хороший материал об этом.
Как все мы знаем, JavaScript без проблем позволяет создавать огромные функции, которые решают сразу множество задач.
Если вы — новичок в программировании, то вам это может показаться чем-то позитивным. О себе скажу, что в былые времена я прекрасно себя чувствовал, когда писал здоровенные куски кода, которые делали то, что мне было нужно. Это имело значение, преимущественно, для меня. Я увереннее чувствовал себя, когда видел, что мой код работает без проблем, уже не говоря о том, что мою уверенность в себе подкрепляло то, что я способен написать громадный блок хорошо работающего кода. Каким же наивным я был тогда!
Если вы хотите писать код, который будет легко поддерживать, код, который устроен просто и не слишком сильно подвержен ошибкам, то вам лучше всего стремиться к тому, чтобы ваши функции были бы как можно проще и меньше. Чем проще функция — тем легче тестировать её в изоляции от других частей системы.
Это особенно важно для тех, кто стремится использовать в своей работе принципы функционального программирования. В этой связи можно вспомнить об одном общеизвестном требовании к функциям: функция должна решать всего одну задачу и ей необходимо решать эту задачу очень хорошо.
В JavaScript-программировании, при передаче JSON-данных методу JSON.parse, надо учитывать то, что этот метод ожидает получить, в качестве первого аргумента, правильно оформленный JSON-код. Если этот метод получит JSON-материалы, с которыми что-то не так, он выбросит ошибку.
Опасность тут заключается в том, что передача JSON.parse некорректного JSON-кода приводит к остановке приложения. На работе я недавно столкнулся с ситуацией, когда один из наших веб-проектов выдавал ошибки из-за того, что один из внешних пакетов не помещал JSON.parse в блок try/catch. Это заканчивалось сбоем при работе страницы, и мы никак не могли избавиться от проблемы до тех пор, пока не был исправлен код внешнего пакета. Происходило же всё это из-за того, что в коде, в процессе его работы, появлялась необработанная ошибка:
SyntaxError: Unexpected token } in JSON at position 107
Обрабатывая JSON-данные, поступающие в приложение из внешних источников, нельзя надеяться на то, что они будут правильно оформленными. Всегда нужно быть готовым к тому, что в них может встретиться что-то такое, что вызовет ошибку.
Надеемся, приведённые здесь рекомендации по улучшению надёжности JavaScript-кода вам пригодятся.
Уважаемые читатели! Что вы посоветовали бы тем, кто хочет писать более качественный и надёжный код на JavaScript?
Автор: ru_vds
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/346550
Ссылки в тексте:
[1] Image: https://habr.com/ru/company/ruvds/blog/487682/
[2] Вот: https://github.com/request/request/blob/master/lib/querystring.js
[3] request: https://github.com/request/request
[4] Redux: https://redux.js.org/
[5] TypeScript: https://www.typescriptlang.org/index.html
[6] Вот: https://geekflare.com/javascript-unit-testing/
[7] Image: https://ruvds.com/ru-rub/#order
[8] Источник: https://habr.com/ru/post/487682/?utm_source=habrahabr&utm_medium=rss&utm_campaign=487682
Нажмите здесь для печати.