Category: JavaScript

09
Дек
2019

Используйте модули для создания модульного приложения JavaScript

От автора: одна из главных особенностей ES6 — поддержка JavaScript встроенных модулей. Модули позволяют совместно использовать код различными файлами, используя синтаксис export и import. Это значительное улучшение по сравнению с использованием тегов script и глобальных переменных для совместного использования кода. Использование тегов script было сопряжено с ошибкам, так как порядок загрузки имеет значение. Указание script […]

07
Дек
2019

Redux и Vuex: правая и левая палочки Twix

Абсолютно разные создатели, совершенно разные фабрики и такие разные библиотеки для управления состоянием. Попробуй обе и реши – на чьей стороне ты?

Redux и Vuex – это две совершенно разные библиотеки или одно и то же в разной обертке? Пора разобраться в этой загадке. Начнем с начала – с понимания задачи, которую они пытаются решить.

Управление состоянием

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

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

Выход есть, говорят нам создатели Redux и Vuex. Вам нужно просто собрать все-все-все данные приложения в одном месте, назвать это хранилищем или состоянием и взаимодействовать только с ним.

Если какой-нибудь компонент хочет изменить состояние, он обращается напрямую к хранилищу. Если другому компоненту требуется вывести данные, он запрашивает их напрямую у хранилища.

Каждый компонент приложения взаимодействует напрямую с хранилищем состояния

Чем ветвистее дерево компонентов, тем очевиднее преимущества такой схемы. Если что-то идет не так, вы всегда знаете, где искать проблему. Такие проекты легко тестировать и расширять, так как разные компоненты мало зависят друг от друга.

Одна цель

Redux и Vuex созданы для решения одной и той же задачи – управления состоянием большого приложения. Возможно, они делают это принципиально разными способами, давайте посмотрим.

Хранилище состояния

И в Redux, и во Vuex данные приложения хранятся в виде обычного объекта. На самом деле, в JavaScript довольно сложно придумать другой способ, так что особого выбора у них не было.

Но просто собрать все данные в одном месте недостаточно, это вы и сами можете сделать. Создатели обеих библиотек тоже так подумали, поэтому хранилище помимо данных содержит еще и методы взаимодействия с ними.

Redux

Создадим хранилище Redux:

            const store = new Store(reducers, initialState); 
        

В reducers передается набор обработчиков, изменяющих данные. Как именно происходит этот процесс, мы увидим чуть позже. initialState – это исходные данные, которые нужно положить в хранилище в самом начале работы.

У хранилища в Redux есть несколько полезных методов:

  • getState() – получение актуального состояния;
  • dispatch() – вызов действия для изменения состояния;
  • subscribe() – подписка на изменения.
Хранилище в Redux и его взаимодействие с компонентами

Vuex

А вот так создается хранилище во Vuex:

            new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {},
}); 
        

Сами данные хранятся в объекте state. getters, как вы, вероятно, догадались, будет содержать геттеры для получения информации. С mutations и actions разберемся чуть позже, сейчас достаточно понимать, что их основное предназначение – изменять данные в хранилище.

Одна идея

Между хранилищами в Redux и Vuex нет принципиальной разницы, но есть организационная. Объект с данными прячется внутри некоторого Store и его изменение осуществляется только опосредованно – через мутации (Vuex) или действия (React). Это позволяет защитить данные от неконтролируемых прямых изменений.

Перейдем к реализации взаимодействия компонентов с хранилищем.

Получение данных

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

Redux

Redux обзавелся специальным методом getState(), который возвращает все состояние приложения разом.

            <HelloWorld text={store.getState().text} /> 
        

Для отслеживания изменений данных и реакции на них обычно используется какая-нибудь дополнительная система UI-биндинга, например, библиотека react-redux (при использовании Redux в React-приложениях). Но при желании вы можете напрямую подписаться на обновления состояния с помощью метода subscribe.

            store.subscribe(() => console.log(store.getState())) 
        

Vuex

Во Vuex вы можете обратиться к свойствам напрямую, достав их из store.state:

            computed: {
  count() {
    return this.$store.state.count;
  }
} 
        

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

Пример из документации:

            // определяем геттер при создании хранилища

const store = new Vuex.Store({
  state: {
    todos: [ ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done);
    }
  }
});

// затем обращаемся к нему в компоненте

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
} 
        

Во Vuex есть еще несколько плюшек, облегчающих труд разработчика (вроде mapState), но они не вносят радикальных перемен в концепцию.

Что касается отслеживания изменений данных, вы можете полностью положиться на Vuex. Хранилище реактивно, поэтому компоненты, полагающиеся на его состояние, будут автоматически обновляться при необходимости.

Разные методы

Получение данных из хранилища не ведет к изменению состояния приложения, поэтому тут обе библиотеки действуют примерно одинаково. Они дают возможность получить данные тем или иным относительно простым способом.

Изменение данных

Переходим к самому интересному – изменению данных в хранилище. Это ключевой момент, влияющий на все приложение. Здесь важно сохранить новые данные, не потеряв при этом все остальное.

Redux

В основе философии Redux лежит понятие иммутабельности (неизменяемости). Нельзя изменить объект с данными, можно только заменить его целиком. Никаких сайд-эффектов, никаких неприятных сюрпризов – только чистый функциональный подход.

В Redux есть лишь один законный способ изменить состояние приложения – совершить действие (actions).

Экшн – это самый обычный объект, который описывает происходящее изменение. Например, он может выглядеть вот так:

            let action = {
  type: 'ADD_USER',
  user: {name: 'Dan'}
}; 
        

Поле type – обязательное, оно содержит тип действия. Все остальное зависит только от вас.

Теперь это действие нужно передать в хранилище с помощью метода dispatch:

            store.dispatch(action);
 
        

Как именно это действие изменит существующее состояние? Для этого предназначены редьюсеры (reducers), о которых мы уже говорили. Это обычные функции, которые получают на вход старое состояние и действие (экшн), а возвращают новое состояние.

            const someReducer = function(state, action) {
  ...
  return newState;
} 
        

Все очень просто:

  1. Какой-нибудь компонент хочет изменить состояние и диспатчит соответствующий экшн.
  2. Оно прогоняется через редьюсеры, которые анализируют тип действия и вносят необходимые изменения.
  3. Возвращенный цепочкой редьюсеров объект становится новым состоянием приложения.

Философия Redux требует, чтобы редьюсеры соответствовали концепции чистых функций (pure functions), то есть не имели никаких побочных эффектов и не зависели от внешних условий.

Vuex

Во Vuex тоже всего один законный способ изменять состояние – мутации (mutations).

Каждая мутация имеет собственное название и соответствующую ей функцию-обработчик. Все мутации описываются при инициализации хранилища.

            const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state, count) {
      state.count += count
    }
  }
}); 
        

Первым параметром передается текущее состояние, вторым – дополнительные данные мутации (нагрузка). Внутри мутации мы просто обращаемся к свойству state.count напрямую.

Вызов мутации во Vuex очень похож на вызов экшна в Redux:

            store.commit('increment', 10); 
        

Каждая мутация состояния отслеживается и реактивно передается компонентам.

Разные понятия

На первый взгляд, подходы Vuex и Redux к изменению состояния принципиально отличаются. Редьюсеры и иммутабельность данных против мутаций. Разные концепции, разные понятия, но суть для разработчика одна: не лезь в данные напрямую, используй только разрешенные методы изменения.

Redux несколько серьезнее относится к отсутствию сайд-эффектов, Vuex предоставляет несколько более интуитивный интерфейс.

Асинхронное изменение данных

Асинхронность – одна из основных концепций JavaScript в целом. Асинхронных действий в вебе не меньше (а может и больше), чем синхронных. Представим простую асинхронную задачу.

Есть компонент-кнопка, при нажатии на которую отправляется запрос на сервер. Пока не получен ответ, нужно вывести прелоадер, чтобы пользователь знал, что что-то происходит. Затем нужно отобразить полученные данные (например, вывести табличку) или показать ошибку, если запрос завершился неудачно.

Redux

В Redux нет асинхронной функциональности из коробки.

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

Vuex

Мутации в Vuex тоже являются синхронными, внутри них нельзя отправлять запросы к серверу. Но у библиотеки тут есть козырь в рукаве – действия (не путать с действиями в Redux).

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

            const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
}); 
        

Вызвать такое действие не сложнее, чем запустить мутацию:

            store.dispatch('increment'); 
        

Внутрь действия может быть помещена любая асинхронная логика.

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

Обратите внимание: действия являются лишь оберткой над мутациями – единственным законным способом изменения состояния.

Разные возможности

Что ж, тут Vuex из коробки обошел Redux, создав собственную (и весьма простую!) асинхронную функциональность.

Правая и левая палочки Twix

Redux и Vuex – это две палочки Twix. Они производятся на разных фабриках и по уникальным технологиям, но в итоге мы имеем очень похожие продукты.

На палочку Redux карамель льется волнами, а на палочку Vuex – струится:

  • Redux многословнее и строго придерживается принципов функционального программирования.
  • Vuex понятнее для изучения и проще при разработке.

На палочку Redux шоколад наливается вертикально, а на палочку Vuex – сверху вниз:

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

А чему отдаете предпочтение вы?

29
Ноя
2019

Что такое super() в JavaScript?

От автора: что происходит, когда вы видите некоторый JavaScript, который вызывает super()? В дочернем классе вы используете super() для вызова конструктора его родителя и super.&ltmethodName> для доступа к методам его родителя. Эта статья предполагает хотя бы небольшое знакомство с понятиями конструкторов и дочерних и родительских классов. Super не уникален для Javascript — многие языки программирования, […]

28
Ноя
2019

Готовящиеся к выпуску новые функции JavaScript

От автора: после релиза ECMAScript2015 (также называемого ES6) JavaScript изменился и улучшился. Это отличная новость для всех разработчиков JavaScript. Кроме того, новая версия ECMAScript выпускается каждый год. Скорее всего, вы не заметили, какие функции были добавлены в последнюю версию ECMAScript, выпущенную в июне 2019 года. Я кратко расскажу вам о новых функциях, добавленных в последней […]

19
Ноя
2019

Написание асинхронных задач в современном JavaScript

От автора: в этой статье мы исследуем эволюцию JavaScript в аспекте асинхронного выполнения от прошлой эпохи и до того, как он изменил способ написания и чтения кода. Мы начнем с начала веб-разработки и пройдем весь путь до современных примеров асинхронных шаблонов. JavaScript, как язык программирования, имеет две основные характеристики, обе важны для понимания того, как […]

18
Ноя
2019

Раскрываем тайну JavaScript sort()

От автора: в JavaScript есть метод sort(), который вы можете использовать в массивах. Но результаты почти всегда странные и не дают того, что вы изначально ожидали. Так, например, если у вас есть следующий массив [9, 8, 12, 1, 33, 21], sort() вернет [1, 12, 21, 33, 8, 9]. На первый взгляд, это не имеет смысла, […]

12
Ноя
2019

Советы по оптимизации JavaScript и улучшению загрузки сайта

От автора: в современном цифровом мире важно оставаться конкурентоспособным. Одним из параметров сохранения конкурентоспособности веб-сайтов является время загрузки. Если ваш сайт работает медленно, вы наверняка потеряете трафик, у вас будет более высокий показатель отказов и меньший оборот. Это означает, что с точки зрения бизнеса одним из наиболее важных аспектов, которые вам необходимо учитывать с самого […]

07
Ноя
2019

await верхнего уровня

От автора: await верхнего уровня позволяет разработчикам использовать ключевое слово await вне асинхронных функций. Оно действует как большая асинхронная функция, заставляя другие модули import ожидать ее, прежде чем они начнут оценивать тело. Старое поведение Когда async/ await был впервые введен, попытка использования await вне функции async приводила к SyntaxError. Многие разработчики использовали сразу вызываемые выражения […]

06
Ноя
2019

Как создать эффект расширения пунктов меню при наведении мыши

От автора: вы когда-нибудь использовали в проекте плагин WordPress Slider Revolution? Если ответ «да», вы могли заметить мини-панель инструментов, которая появляется в правом углу страницы конфигурации плагина. Первоначально видны только иконки, что делает все это красивым и компактным. Затем каждый раз при наведении курсора происходит расширение текста под ним. В этом руководстве давайте почерпнем вдохновение […]

06
Ноя
2019

Создание макета панели администрирования с помощью CSS и JavaScript

От автора: в этом руководстве мы создадим адаптивный макет панели администрирования с помощью CSS и немного JavaScript. Чтобы создать его, мы позаимствуем некоторые идеи из панели управления WordPress, например, ее боковое меню. В процессе создания мы столкнемся со множеством проблем, но они дадут нам хорошую практику для повышения навыков. Что мы будем создавать Без дальнейших […]

05
Ноя
2019

7 на первый взгляд простых вопросов на собеседовании по JavaScript

От автора: самые стрессовые для меня вещи в разработке программного обеспечения это: собеседование по кодированию и дотошный менеджер или товарищ по команде. Не JavaScript, не this, не CSS, не Internet Explorer, а именно эти две вещи. Если вы претендуете на должность старшего разработчика, который использует JavaScript, есть высокий шанс того, что вам зададут во время […]

03
Ноя
2019

Composition API во Vue 3 — плюсы, минусы и опыт использования

В Vue 3 на смену Options API приходит Composition API. Что это, где его применять, как он может упростить разработку, рассказывает Тихон Соколов
— Читать дальше «Composition API во Vue 3 — плюсы, минусы и опыт использования»

01
Ноя
2019

Создание JavaScript приложения для распознавания лиц, как в кино

От автора: когда мы смотрим фильмы, действие которых происходит в будущем, мы часто видим, как персонажи смотрят на экран компьютера, пытаясь отсканировать лица людей, таких как преступники, или тех, кого они хотят преследовать. Прямо сейчас технология распознавания лиц настолько развита, что это стало реальностью. Мы можем создавать приложения, которые могут распознавать лица с большой точностью. […]

01
Ноя
2019

Как обнаружить блокировщик рекламы

От автора: одно из неписанных правил Интернета заключается в том, что большая часть контента является «бесплатной»… за счет того, что веб-страница содержит рекламу и трекеры. В первые дни интернета это не было большой проблемой, но трекеры и рекламные объявления стали настолько навязчивыми и агрессивными, что вам почти обязательно нужно использовать расширение для браузера, блокирующее рекламу. […]

25
Окт
2019

Вышел Node.js 13.0 с обновлённым движком V8 и улучшенной поддержкой Python 3

Ещё разработчики добавили полную поддержку Unicode и стабилизировали API Workers Threads для создания многопоточных циклов обработки событий.
— Читать дальше «Вышел Node.js 13.0 с обновлённым движком V8 и улучшенной поддержкой Python 3»

25
Окт
2019

Новые и готовящиеся функции JavaScript ES2019

От автора: с самого начала JavaScript прошел долгий путь со многими новыми дополнениями и функциями, специально разработанными для того, чтобы сделать язык более удобным и менее многословным. Ниже приведены некоторые недавние добавления в JavaScript, которые я нахожу захватывающими. Некоторые из этих функций уже доступны в Node, Chrome, Firefox и Safari, в то время как другие […]

23
Окт
2019

2 ноября, Гродно: конференция GROCON’19

В четвертый раз пройдёт крупнейшая в регионе IT-конференция. Её программа разделена на 4 потока: Adapt IT, Maintain IT, Manage IT, Unite IT.
— Читать дальше «Конференция GROCON’19»

23
Окт
2019

Нативный javascript: 6 функций, о которых вы не знаете

От автора: JavaScript — это язык, который быстро развивается; по этой причине иногда трудно уследить за всеми все его функциями и возможностями. В этой короткой статье мы рассмотрим некоторые нативные функции, о которых вы, возможно, не знали. Получение параметров строки запроса URLSearchParams это интерфейс, который позволяет обрабатывать параметры строки запроса, он существует уже несколько лет, […]

17
Окт
2019

8–9 ноября, Москва: конференция HolyJS 2019 Moscow

Обсудят тренды и технологии, используемые в стремительно развивающейся экосистеме. Среди спикеров — опытные разработчики и авторы технологий и инструментов.
— Читать дальше «Конференция HolyJS 2019 Moscow»

16
Окт
2019

Необходимый минимум для фронтенд-разработчика

На днях я подготовила README для одного проекта, который, надеюсь, будет интересен и поучителен для других разработчиков. Так вот, когда я его писала, я поняла, что несколько лет назад испугалась бы до смерти, если бы наткнулась на нечто подобное, со всякими упоминаниями о Node и его пакетном менеджере, системах Homebrew и Git, всевозможных тестах, тестовых и финальных сборках.

15
Окт
2019

Самая крутая новая функция в Javascript: Опциональное объединение в цепочку

От автора: опциональное объединение в цепочку меняет правила игры для всех, кто работает с Javascript. Это так же важно, как стрелочные функции или «let» и «const». Давайте рассмотрим, какие проблемы оно решает, как оно работает и как он облегчит вашу жизнь. Проблема Представьте себе следующее: вы работаете над тем фрагментом кода, который загружает данные из […]

13
Окт
2019

Кэширование кода для JavaScript-разработчиков на примере Chrome

Кэширование кода на примере браузера Chrome: какую роль оно играет для оптимизации работы сайтов, а также какие бывают виды кэша.
— Читать дальше «Кэширование кода для JavaScript-разработчиков на примере Chrome»

11
Окт
2019

17 октября, Москва: митап MSK VUE.JS #4

Поговорят о перспективах развития фреймворка, обсудят темы «Vue Composition (Function) API», «Как сколотить состояние на Vue», «Запись аудио в браузерах».
— Читать дальше «Митап MSK VUE.JS #4»

09
Окт
2019

Должен ли сайт работать без JavaScript?

От автора: подкаст JS Party только что выпустили интересный эпизод, в котором они обсуждали этот классический вопрос, разделившись на две группы по два человека. Каждой группе была назначена «сторона» этой дискуссии, а затем они начали обсуждения. Я не думаю, что кто-то может слушать подобное шоу и хотя бы немного не задумался над одним из этих […]

03
Окт
2019

Как найти ошибки в коде JavaScript с помощью отладчика

От автора: знаете ли вы, что в JavaScript встроен отладчик? Отладчик полезен, когда дело доходит до поиска ошибок и обхода вложенных обратных вызовов, promise и т. д. Этот отладчик работает как с отрисованным кодом на стороне клиента, так и на стороне сервера. Синтаксис [crayon-5d95b2354860f127933802/] Объявление debugger позволяет остановить выполнение кода и проверить любые переменные, значения […]