Что необходимо знать каждому Javascript разработчику. Язык программирования JavaScript: информация для начинающих

15.03.2019

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

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

Почему JavaScript?

Стоит отметить открытость языка - компании, обычно соперничающие друг с другом, сотрудничают с целью развития JavaScript. Язык очень гибок и подойдёт сторонникам как объектно-ориентированного, так и функционального подхода. Огромное количество библиотек и фреймворков позволяет с лёгкостью решать любые типы задач, а серверная платформа Node.js даёт возможность использовать язык не только в браузере, но и в консоли. Вы даже можете писать настольные и мобильные приложения: первые - при помощи фреймворка Electron, а вторые - на NativeScript или React Native.

Основы

Сперва необходимо изучить основные понятия JavaScript, веб-разработки и программирования в целом:

  • объектно-ориентированный JS - конструкторы и фабрики, наследование;
  • функциональный JS - функции высшего порядка, замыкания, рекурсия;
  • спецификации тестов Jasmine;
  • основы HTML, CSS и jQuery.

Git

Git - необходимый разработчикам инструмент, поэтому с ним нужно как можно раньше. Вот основные навыки, которыми вы должны обладать:

  • создание и перемещение файлов в каталогах;
  • инициализация и коммиты в Git;
  • настройка репозиториев в GitHub.

Алгоритмы и структуры данных

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

Бэкенд

Node.js

10 лет назад JavaScript можно было использовать только для фронтенд-разработки. Теперь благодаря Node.js одним «фронтом» дело не ограничивается. Node - это просто среда для выполнения JS-кода на стороне сервера, поэтому вам не придётся изучать новый синтаксис, но понадобится импортировать и экспортировать файлы, разбивать код на модули и использовать менеджер пакетов npm.

Серверы, HTTP, Express.js

После изучения Node стоит продолжить знакомство с бэкенд-разработкой и разобраться в серверах и маршрутизации. Можно начать с портов и протоколов с акцентом на HTTP, а потом заняться Express - Node-библиотекой для обработки запросов.

Асинхронный JavaScript

Базы данных, схемы, модели и ORM

Базы данных - один из важнейших элементов веб-разработки. Если вашему приложению нужно загружать или хранить какие-либо данные, не теряющиеся при обновлении страницы, придётся использовать БД. Нужно научиться различать реляционные и нереляционные базы данных и разобраться в типах связей. Затем и познакомиться с разными . Умение работать с ORM тоже не будет лишним.

Фронтенд

HTML и CSS

HTML и CSS - это основа основ для любого веб-разработчика. Вам не обязательно знать их в совершенстве, но разбираться в них вы должны. Также можно изучить какую-нибудь популярную библиотеку (например, Bootstrap) и CSS-препроцессор вроде Sass - он поможет сделать CSS похожим на обычный код. Для упрощения работы с HTML можно выбрать один из популярных шаблонизаторов, например, pug.

jQuery и манипуляция DOM

Создав внешний облик страницы при помощи HTML и CSS, вы будете использовать и библиотеку jQuery для управления DOM. Многие считают, что jQuery бесполезна и её скоро заменят Angular и React, но она безумно популярна, и поэтому её стоит знать. Кроме того, однажды вы попадёте в ситуацию, когда забивать гвозди React-микроскопом вам будет неудобно, и тогда на помощь вам придёт лёгкая jQuery.

Инструменты разработчика Chrome

Было бы непростительно обделить вниманием инструменты Chrome , которые дают огромное количество возможностей. С ними вы сможете изучать элементы DOM, производить отладку через консоль, отслеживать маршруты и многое другое. В описаны несколько удобных возможностей консоли Chrome, которые упростят выполнение рутинных задач.

AJAX

Если вы хотите, чтобы приложение не перезагружало страницы после каждой операции с базой данных, вам точно понадобится AJAX - он отправляет фоновые асинхронные HTTP-запросы, ответы на которые обновляют лишь часть отображения. Работать с AJAX можно через jQuery при помощи метода.ajax .

Продвинутые темы

Разработка через тестирование

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

Веб-сокеты

Этой теме стоит уделить особое внимание, поскольку очень полезны. Протокол WebSocket, в отличие от HTTP, позволяет работать с двунаправленным потоком данных, что делает эту технологию уникальной. Самой распространённой реализацией является библиотека socket.io - разобраться с ней и применить полученные навыки на практике поможет по созданию многопользовательской браузерной игры.

ES6, Babel, Webpack

Сейчас основным стандартом является ES6 (ES2015), но уже принят ES2016, а ES2017 находится в разработке, поэтому нужно всегда быть в курсе обновлений и использовать их. Проблемы совместимости решаются всего парой инструментов:

  • Babel - компилирует ES6-код (скоро появится поддержка ES2016) в ES5, который поддерживается всеми браузерами. Он даже умеет компилировать JSX/React-компоненты, что делает его незаменимым для любого веб-разработчика;
  • Webpack - собирает все ваши исходные файлы (картинки, шрифты, таблицы стилей, JS-файлы и т.д.) в единый граф зависимостей. Он не пригодится при создании маленьких приложений, но при работе с React его помощь неоценима.

React и Redux

React - библиотека для создания пользовательских интерфейсов. Она была создана компанией Facebook в 2013 году и достаточно быстро стала популярной среди разработчиков. Вам стоит прочитать , а затем разобрать , чтобы понять, как работает React и для чего он нужен. React пригодится не только для фронтенд-разработки: Facebook выпустила варианты фреймворка для мобильной (React Native) и VR-разработки (React VR).

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

Аутентификация, сессии, cookies

Вам также стоит разобраться, как приложения взаимодействуют с пользователями, обрабатывают вход в учётную запись и выход из неё, выдают привилегии. Для отслеживания личности пользователя в течение сессии используются cookies - небольшие текстовые файлы, передаваемые сервером браузеру в ответе на HTTP-запрос. А для обеспечения связи базы данных и страничек авторизации можно использовать библиотеку express-session.

Веб-безопасность

И, наконец, стоит обратить внимание на безопасность. Важно изучить как методы атак, так и способы защиты от них.

Для работы будем использовать такую вещь как CPS.

Звучит гораздо страшнее, чем есть на самом деле. Это функция, которая получает в качестве параметра другую функцию, и когда первая функция завершается, она вместо retrun вызывает функцию-параметр.

Обернем jQuery.ajax таким образом, чтобы получить требуемый результат.

Function ajax(url, callback){ jQuery.ajax({url: url, success: callback}); }

Функция получает в качестве параметера callback, и мы не описали обработчик ошибок. В реальном коде он обязан быть, но для простоты изложения, мы о нем забудем.
Что же будет, если использовать библиотеку async? Получится что-то типа такого:

Function combine(scripts, callback){ async.map(scripts, ajax, function(contents){ callback(contents.join("")); }); }

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

Сравните с тем, что было:
function combine(scripts, callback){ var data ; for(var i =0; l = scripts.length; i< l; ++i){ (function (i){ jQuery.ajax({ url: scripts[i], success: function(response){ data[i] = response; if(data.length === scripts.length){ callback(data.join("")); } } }); }(i)); } }

Поскольку map для меня уже является естественным способом написания программ, я бы никогда не написал кода приведенного выше. Я бы думал, как приспособить map к асинхронному окружению. И если бы не было библиотеки async, то написал бы асинхронный map сам.

Функциональный подход позволяет гораздо проще смотреть на вещи. И реализовывать более красивые решения.

Частичное применение функций

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

В качестве примера мы будем создавать DOM элементы.
(Прим. переводчика: cull.dom - библиотека, автора, которую он создавал для одного из проектов. Но функции в ней очевидны и просты.)

Var ul = cull.dom.el("ul"); //document.createElement("ul") ul.nodeType === 1 // true

Также можно задавать атрибуты свойств.

Var ul = cull.dom.el("ul", {className: "bands"});

И указывать дочерние элементы

Var li = cull.dom.el("li", "Tom Waits"); var ul = cull.dom.el("ul", {className: "bands"}, li);

Если их использовать друг внутри друга, можно получить некое подобие DSL для HTML.

Va ul = cull.dom.el("ul", className:"bands"}, cull.dom.el("li", "Tom Waits"));

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

Function makeAdder(base){ return function(num){ return base + num; } }
Он возвращает функцию, которая будет суммировать два числа. Естественно, при необходимости мы можем использовать именованные функции.

Function makeAdder(base){ return function(num){ return add(base, num); } }

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

Var add2 = cull.partial(add, 2); add2(5); //7

Теперь мы получили достаточно интересную возможность - сделать наш DSL по созданию DOM элементов еще красивее.

Var ul = cull.partial(cull.dom.el, "ul"); var li = cull.partial(cull.dom.el, "li");

И можем строить HTML списки приблизительно так

Var list = ul({className: "bands"}, );

Если вы как и я, не любите программировать на уровне строковых переменных - это отличный способ упростить себе жизнь. У вас теперь будет работать автодополнение кода, и другие приятные вещи. А еще ваш код очень похож на обычный HTML.
И поскольку наш подход достаточно красив, мы можем создать функции для всех элементов документа заранее:

["a", "br", "code", "div", ...].forEach(function(tagName){ cull.dom.el = cull.partial(cull.dom.el, tagName); });

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

Var e = cull.dom.el; var list = ul({className: "bands"}, );

Теперь мы не завязаны на глобальные переменные и функции, что хорошо.

Композиция функций

Вот еще пример простого приложения - опросника.

Необходимо ответить на каждый блок. Каждый блок содержит несколько вопросов. После ответа на один блок, мы переходим к следующему.

Каждый блок можно представить как панель, которая может быть в режиме вопроса, режиме результата или неактивной.

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

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

Помните нашу любимую функцию prop ?

Tweeps.map(prop("name"));

У нее есть брат-близнец func .

Tweeps.map(func("to.String"));
Она возвращает функцию, которую вы можете применять к объектам.

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

BuildSummary: function(){ return div(this.components.map(func("buildSummary"))); }

Принцип должен быть очевиден. Мы возвращаем div, в котором будут элементы, созданные функцией buildSummary для каждого блока опросника.

В этом примере каждый компонент сам знает как представить свой результат. Но иногда панель должна отобразить результат специфическим образом.

Поэтому мы можем написать 2 функции: buildSummary и getSummary .

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

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

BuildSummary: function(){ var div = document.createElement("div"); for(var i =0; l=this.components.length; i

Однако, мы уже достаточно функционально ориентированы, чтобы улучить этот кусок кода. Первое очевидное улучшение - применить foreach.

BuildSummary: function(){ var div = document.createElement("div"); this.components.forEach(function(component){ var p = document.createElement("p"); p.innerHTML = component.getSummary().text; div.appendChild(p); }); return div; }

Мы избавились от переменных цикла, но возможно ли использовать map ?

BuildSummary: function(){ return div(this.components.map(function(component){ var p = document.createElement("p"); p.innerHTML = component.getSummary().text; return p; })); }

Коротко, но далеко до идеала. Основная проблема в этом выражении:
component.getSummary().text;

Проблема в том, тут происходит не одна, а целых три вещи:

  1. Получение результата через getSummary()
  2. Получение свойства text
  3. Оборачивание результата в тег p

А как насчет нескольких функций map?

BuildSummary: function() { return div(this.components. map(function(component){ return component.getSummary(); }).map(function(summary){ return summary.text; }).map(function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; })); }

Функциональный стиль налицо, но выглядит страшно. И читать очень неудобно.

Но давайте глянем на код еще разок. Что у нас здесь?

Return component.getSummary();

Здесь мы вызываем метод объекта. Но ведь мы создали специальную функцию для этого, func .

BuildSummary: function() { return div(this.components. map(func("getSummary")). map(function(summary){ return summary.text; }).map(function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; })); }

Function(summary){ return summary.text; }

Мы получаем доступ к свойству объекта. И для этого тоже есть удобная функция.

BuildSummary: function() { return div(this.components. map(func("getSummary")). map(prop("text")). map(function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; })); }
Остался последний участок.
function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; }

Мы здесь создаем DOM элемент и устанавливаем его внутреннее свойство. У нас есть что-то похожее в нашем DSL, не правда ли?

BuildSummary: function() { return div(this.components. map(func("getSummary")). map(prop("text")). map(p)); }
Теперь почти красиво. Но есть один нюанс. Мы делаем 3 прохода по списку. В каких-то случаях это может быть нормально, но в целом несколько неоптимально. Что же можно сделать?

Пора использовать композицию функций. Мы хотим заставить одну функцию делать то, что делают три.

Var summarize = compose();

Как же нам реализовать compose?

По частям. Для начала создадим синонимы, чтобы не писать много кода.

Var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose();

Шаг первый

var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose(); // summarize(obj); // => callGetSummary(obj)
Объект предеается в последнюю функцию из списка, а именно getSummary . Она возвращает нам объект типа summary . А этот объект передается в следующую функцию, getText

Шаг второй

var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose(); // summarize(obj); // => getText(callGetSummary(obj))

В результате второго шага мы получим строку, которая содержится в свойстве text . А после этого строка попадет в функцию, которая создаст нам DOM объект p .

Шаг третий

var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose(); // summarize(obj); // => p(getText(callGetSummary(obj)))

Это пример простой композиции, когда параметр передается из функцию в функцию последовательно. Можно создать композицию, когда параметр будет передаваться в каждую функцию, и на выходе будет список результатов. Или еще как-то.

Итак, вернемся к нашему многострадальному примеру.

BuilSummary: function() { var summarize = compose(); return div(this.components.map(summarize)); }

Сначала мы создали функцию вычисления результатов. А потом применили map.
При этом заметьте, что функция summarize абсолютно не знает, с каким объектом она работает. Это три различных абстракции, которые соединяются исключительно благодаря функции compose. Поэтому мы можем вынести summarize в отдельную сущность.

Var summarize = compose(); // ... builSummary: function() { return div(this.components.map(summarize)); }

Выглядит здорово и красиво, но что насчет производительности?

Вопросы производительности

For - 5M операций в секунду
forEach - 1,5M операций в секунду
reduce - 1.5M операций в секунду

Работа с DOM - 50K операций в секунду

Так что беспокоиться стоит не о функциональном подходе, а о тормозах работы с DOM. Само собой, тут все зависит от вашей задачи, поэтому если сомневаетесь - делайте замеры. Особенно на мобильных устройствах.

Заключение

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

P.S. Слайды оригинального выступления можно посмотреть по адресу

Javascript - постоянно развивающийся язык, особенно сейчас, когда установлен ежегодный график выхода обновлений спецификаций ECMAScript. В связи с этим важность знания Javascript за пределами jQuery возрастает.

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

Учитывая эти аспекты, начнем…

Что такое FizzBizz тест

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

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

Помните, вероятность того, что вас попросят выполнить подобный тест на собеседовании, очень велика.

Пример классического FizzBizz теста:

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

For (var i = 1; i <= 100; i++) { if (i % 15 == 0) { console.log("FizzBuzz"); } if (i % 3 == 0) { console.log("Fizz"); } if (i % 5 == 0) { console.log("Buzz"); } }

Разница между == и ===

Вы, наверняка, знакомы с обоими операторами сравнения. Тем не менее, а знаете ли в чем точно отличаются эти операторы? Ваш Javascript Linter требует от вас применения оператора ===, задумывались почему?

Не сравнивает типы операндов, вместо этого он приводит их к одному типу. Такая операция имеет негативную репутацию.

Console.log(24 == "24"); // true

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

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

Тот же самый пример, но с оператором ===

Console.log(24 === "24"); // false

В ответ мы получаем false , так как операнды разного типа, один из них целочисленного типа, а второй строкового.

Как выбирать элементы DOM без дополнительных библиотек

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

Я имею ввиду не просто выбрать элемент с определенным ID или набором классов, я говорю о выражениях для поиска элементов при помощи jQuery.

Существует несколько нативных методов для поиска элементов в DOM, которые ни чем не уступают jQuery. Мы можем также использовать селекторы вида first-child , last-child и т.д.

Познакомимся с некоторыми из этих методов

  • document.getElementById - классический метод для поиска элементов по их ID.
  • document.getElementsByClassName - выборка элементов по значению поля className
  • document.querySelector - отличный метод, который практически полностью заменяет селектор $() от jQuery, но он уже включен в Javascript. Единственное отличие заключается в том, что он возвращает только первый найденный элемент.
  • document.querySelectorAll - аналог предыдущего метода, но возвращает массив найденных элементов.
  • document.getElementsByTagName - этот метод поможет вам выбрать элементы по имени тега. Если вам потребуется найти все div элементы, то вам нужен именно этот метод.

Хочу также отметить, что методы querySelector и querySelectorAll можно использовать не только на всем документе, но и на отдельных элементов, то есть выборку вы можете делать в пределах одного родительского элемента.

В документации от mozilla вы найдете полное описание этих методов.

Поднятие объявлений переменных и функций

Javascript интересен тем, как он обрабатывает объявленные переменные и функции, все они автоматически поднимаются вверх области видимости. Таким образом, вы можете обратиться к ним до их объявления в области видимости (например, функции в javascript имеет собственную область видимости).

Поэтому для удобства чтения кода возьмите себе за правило ВСЕГДА объявляйте переменные в начале области видимости. Если же вы укажите ‘use strict’ в верху скрипта или функции, то при обращении к необъявленной переменной вы получите ошибку.

Большинство инструментов для проверки стиля кода, как Jshint, укажут вам на ошибку если вы не использовали ‘use strict’ , исходя из этого, если вы стараетесь писать хороший код, то вам в любом случае не получится использовать переменные до их объявления. Как всегда, при возникновении вопросов, обращайтесь к документации от mozilla, там вы всегда найдете полное и исчерпывающее описание вашей проблемы.

Использование инструментов разработчика в браузере

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

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

Научившись применять инструменты разработчика в таких браузерах как Chrome, Firefox и в последних версиях Internet Explorer, вы сможете отладить работу вашего скрипта, измерить его быстродействие и найти места, где стоит улучшить алгоритм работы.

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

Команды консоли

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

Наверняка, вы уже знакомы с такими командами как console.log и console.error , но этим функционал консоли не ограничивается.

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

  • console.log - используется для ведения журнала событий. Поддерживает форматирование.
  • console.error - для журналирования ошибок в коде. Я использую эту команду при возникновении ошибок в AJAX запросах и в других потенциально опасных участках кода. Метод похож на предыдущий, но он выводит список вызовов стека.
  • console.dir(object) - выводит форматированное содержание объекта. Как приавло, этот метод очень полезен при отладке кода.
  • console.group(title) - позволяет создать группу сообщений в журнале с названием title. Таким образом вы можете группировать сообщения, например, по тому участку кода, где они генерируются.
  • console.groupCollpased - аналог предыдущей команды за одним исключением. А именно, она выводит сообщения в свернутом виде.
  • console.groupEnd - заканчивает ранее созданную группу.
  • console.time(label) - позволяет отслеживать скорость работы участка в миллисекундах. Метод полезен при отлавливании потенциально сложных участков кода.
  • console.timeEnd(label) - аналог метода groupEnd, но работает он в отношении console.time().
  • copy(string) - в консоли Chrome и Firefox существует метод, позволяющий вам копировать содержимое string в буфер обмена. Очень полезный метод, попробуйте его применить.

Что именно содержится в this

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

В традиционных языках программирования, this содержит ссылку на текущий объект класса. Но так как javascript далек от традиций, то в нем эта переменная ссылается на объект родитель метода.

Самой простой способ понять this , это принимать его за владельца или родителя метода. this всегда ссылается на родителя (parent), за исключением случаев, когда вы исползуете методы call , apply или bind .

В следующем примере this ссылается на объект window:

Function myFunction() { console.log(this === window); // true } myFunction();

Наверняка у вас возник вопрос, как же this может быть равно window , если обращаемся к нему в пределах метода? Если вы знаете ответ на этот вопрос, то отлично, в противном случае читайте дальше и я постараюсь объяснить.

При объявлении функции таким образом, она привязывается к глобальному объекту window . Помните, мы же сказали, что this ссылается на родителя метода?

Изменение значения this на полностью новый объект (не window):

Function myFunction() { console.log(this === window); // false } new myFunction();

Сторонники чистоты кода наверняка в шоке от такого примера. Мы просто ходим по верхушке айсберга с такими примерами. Как видите сами, значение this уже не равно window .

Почему так произошло?

Самое простое объяснение - во втором примере мы использовали ключевое слова new , этим самым мы создали новую область видимости и новый объект.

В следующем примере мы создадим фиктивный API для выгрузки данных из библиотеки от сервера. Мы создадим объект API с некоторыми методами.

При использовании слова new , контекст скрипта переходит от контекста window к API .

Var API = { getData: function() { console.log(this === window); // false console.log(this === API); // true } }; API.getData();

Как видите значение this полностью задается способом вызова метода. Так как функция вызывается в пределах объекта API , её родителя, то значение this ссылается на объект API.

Помните, значение this изменяется. Оно изменяется в зависимости от способа вызова, но если вы используете метод bind , то значение this остается неизменным.

Более подробно с ключевым словом this в javascript вы можете познакомится в статье Quirksmode и документации от Mozilla.

‘use strict’;

Как мы уже указали ранее user strict используется для применения более строгой версии языка javascript. Эту директиву следуют применять во всех скриптах.

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

В документации от mozilla существует целая статья на эту тему, я настоятельно рекомендую вам познакомиться с ней.

Разные виды циклов

Вы будете удивлены, но я встречал огромное количество разработчиков, которые не знали как правильно использовать цикл for и абсолютно не слышали о других типов циклов. А уметь применять цикл на массиве или объекте - очень важный навык для разработчика. Не существует четкой инструкции когда и какой применять тип цикла, но следует ориентироваться в этом вопросе. Наверняка вы знакомы с for и while, но как насчет других?

Список циклов в javascript:

  • for..in
  • for..of (добавлен в ES6)
  • forEach
  • while
  • do..while

Цикл for

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

For (условие 1; условие 2; условие 3) { // Ваш код }

Условие 1 - выполняется один раз перед началом серии циклов. В большинстве случаев вы будете инициализировать здесь счетчик цикла. Этот пункт можно пропустить, если вы произвели инициализацию ранее.

Условие 2 - это условие применяется для определения продолжать цикл или нет. Вы, наверняка, будете здесь сравнивать ваш счетчик с размером массива. Если значение сравнения true, то цикл продолжается. Если вы прерываете цикл внутри при помощи break, то это условие можно пропустить.

Условие 3 - этот участок выполняется после каждой итерации, как правило именно здесь вы увеличиваете ваш счетчик.

Цикл for...in

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

Приведем пример.

Var person = {firstName: "Dwayne", lastName: "Charrington", age: 27, starSign: "Aquarius"}; // The below loop will output: // "Dwayne" // "Charrington" // 27 // "Aquarius" for (var p in person) { if (person.hasOwnProperty(p)) { console.log(person[p]); } }

Цикл for...of

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

Этот цикл полная противоположность for...in , он перебирает значения полей и работает только с типами данных, которые поддерживают итерации, к которым Object не относится.

Var fruits = ["orange", "apple", "squash", "pear"]; for (var fruit of fruits) { console.log(fruit); }

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

Цикл forEach

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

Он работает только с массивами, не объектами. Он выгоден тем, что вам не приходится создавать дополнительные переменные, которые в итоге только загрязняют ваш код.\

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

Var fruits = ["apple", "banana", "orange", "grapes", "pear", "passionfruit"]; // The three values on the callback function are: // element - The element being traversed // index - The current index of the item in the array starting at 0 // array - The array being traversed (probably mostly irrelevant) fruits.forEach(function(element, index, array) { console.log(index, element); });

Иногда вам нужно просто пройти по всем элементам массива и, возможно, внести в них некоторые изменения. Его поведение похоже на jQuery.each.

Один недостаток такого типа циклов - его нельзя прервать. Если вам требуется создать цикл по правилам ES5, то воспользуйтесь методом Array.every , познакомиться с которым вы можете в документации mozilla.

Цикл while

Цикл while аналогичен for , но он принимает только один параметр - само условие, по которому цикл определяет продолжать итерации или прекратить их.

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

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

Var i = 20; while (i--) { console.log(i); }

Цикл do...while

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

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

На этом разница не заканчивается. Цикл while обрабатывает условие до выполнения итерации, а do...while после.

Как всегда в документации от mozilla вы найдете подробное описание такого вида циклов.

Базовые методы и задачи

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

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

Работа со строками

В javascript вы чаще всего будете работать со строковыми данными, за исключением, наверно, массивов и объектов. Даже если вы не работаете со строками, или думаете, что не работаете, то познакомиться с этими методами все же стоит.

  • String.replace(regexp | что заменить, на что заменить, callback) - позволяет заменить часть строки, допускается применение регулярных выражений.
  • String.concat(сторока 1, строка 2...) - соединение нескольких строк в одну.
  • String.indexOf(value) - метод позволяет найти порядковый номер символа искомой части строки, -1 - если строка не найдена
  • String.slice(startIndex, endIndex) - возвращает участок строки от startIndex до endIndex
  • String.split(разделитель, лимит) - разбивает строку на массив по символу разделителя, максимальной длиной лимит.
  • String.subsctr(startIndex, length) - возвращает часть строки начиная с startIndex длиной length.
  • String.toLowerCase - переводит все символы строки в нижний регистр
  • String.toUpperCase - перевод все символы строки в верхний регистр
  • String.trim - удаляет пробелы из начала и конца строки

Работа с массивами

Вам очень часто придется встречаться с массивами. Они отлично зарекомендовали себя как способ хранения данных. Эти методы точно стоит знать любому разработчику javascript, не следует искать их в google.

  • Array.pop -возвращает последний элемент и удаляет его из массива.
  • Array.shift - возвращает первый элемент и удаляет его из массива.
  • Array.push(val1, val2) - добавляет одно или несколько значений в конец массива. Возвращает новую длину массива.
  • Array.reverse - зеркально изменяет порядок элементов массива.
  • Array.sort([функцияСравнения]) - позволяет сортировать массив при помощи собственной функции.
  • Array.join(separator) - Возвращает строку, состоящую из элементов массива, разделенный символом separator (по-умолчанию - запятая).
  • Array.indexOf(value) - возвращает индекс элемента в массиве, -1 если элемент не найден.

Это не полный список методов для работы с массивами. С другими вы можете ознакомится в документации от mozilla. Начиная с ES6 были добавлены очень интересные методы.

Разница между call и apply

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

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

При помощи метода apply вы можете передать аргументы в виде массива и изменить значение this .

Если вам нужно просто передать массив в качестве аргументов методу, то начиная с ES6 добавлен расширенный (spread) оператор. Он не позволяет изменять значение this . Познакомиться с ним вы сможете, как всегда в официальной документации от mozilla.

Пример call:

Function myFunc() { console.log(arguments); } myFunc.call(this, 1, 2, 3, 4, 5);

Пример apply:

Function myFunc() { console.log(arguments); } myFunc.call(null, );

Знакомство с библиотеками и фреймворками

На сегодня самыми заметными представителями javascript фреймворками являются AngularJS, React.js и Ember. Конечно существует еще целый ряд других.

Так как web-приложения становятся все больше и больше эти библиотеку упрощают работу с ними. Стоит понимать, что сейчас знать одного jQuery явно недостаточно. В большинстве вакансий выставляется знание дополнительных javascript библиотек, как основное требование.

Node.js

Вне сомнений Node.js занимает твердые позиции. Практически любой фронт-енд инструмент построен на node.js и использует npm (менеджер пакетов node), если с ним незнакомы, то настоятельно советую исправить это упущение. Так как node.js использует javascript, то изучить его не представляет особых трудностей для тех, кто уже знаком с этим языком. У вас больше времени уйдет на настройку пакетов node, чем на написание самого кода.

Лично я считаю, что с Node должен быть знаком каждый разработчик в 2015 году. Я не говорю о глубоком познании, достаточно уметь применять его для серверной разработки, прототипирования, тестирования и т.д.

Существует fork node.js под названием IO.js, на сегодняшний день они практически аналоги, да и в конце концов вы просто пишите на Javascript за исключением небольших отличий.

Тестирование

Когда-то мы совсем не тестировали javascript код, так как не считали это необходимым. Но скрипты становятся всё больше и больше благодаря AngularJS и Node.js.

Javascript развивается, а объемы скриптов увеличиваются и тестирование становится жизненно необходимым. Если вы не тестируете свой код, то вы поступаете неправильно. Мой любимый тестировщик - Karma. Существуют и другие, но именно этот зарекомендовал себя лучше всех при работе с AngularJS. А если он подходит для AngularJS, то он подходит и мне.

Инструменты

Быть javascript разработчиком в 2015 году означает не только отличное знание языка, но и большого числа инструментов для работы с ним.

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

Вот набор инструментов, о которых стоит помнить: Gulp, Webpack и BabelJS. Существует намного больше инструментов, но такие инструменты как Gulp и Grunt значительно помогают вам в разработке и управлении javascript приложениями.

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

Мы объединяем и минимизируем скрипты, тестируем их, что помогает организовать структуру проекта.

Инструменты javascript идут рука об руку при разработке изоморфного Javascript (код, используемый как на стороне клиента, так и сервера). ECMAScript 6, он же ES6, он ESNext

Браузерам предстоит еще реализовать большую часть функционала ECMAScript 6. Но уже сегодня вы можете использовать новинки от ES6 при помощи компиляторов javascript. Познакомьтесь с новыми API и методами: строки, массивы и другие метода как WeakMaps, Символы и Классы. Следует всегда быть в курсе грядущих изменений.

Заключение

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

Соколов - Томск

30 000 - 65 000 руб.

...Нужен программист для стартапа (Всероссийская база данных мошенников). Архитектура: Сервер ... ...сайта (front-end) на PHP / VueJS или Java. Желательны знания: CSS, Html ... ...Boot, Hibernate) Android, iOS JavaScript Базы данных (Postgres, Mysql) ...

26 дней назад

Чернецов Антон Константинович - метро Ботанический сад, Москва

60 000 руб.

...автоматизированной системы (PLM, CRM, ЭДО). Установка, отладка, написание расширений для корпоративных систем. Написание Java- кода и JavaScript. Отладка большого web-приложения (JavaEE, Tomcat, JSP, JavaScript). Создание схемы БД Требования: ...

26 дней назад

ООО Центральная Касса - Пермь

50 000 - 120 000 руб.

...сложных и интересных задач для разработки современных платежных решений. Сейчас мы применяем большое количество технологий: · Java 8, Spring (+Spring Boot), Redis, Wildfly, PostgreSql, TestNg & Mockito. · Maven, Git, Youtrack, Upsource. Присоединяясь к нашей ...

9 дней назад

ГК Safe Logic - метро Семёновская, Москва

...ищем активных, целеустремленных, ориентированных на результат сотрудников Обязанности: JavaScript программист для разработки проектов на ExtJS 6 и выше Java 1.8 Spring Framework (Core, Data, Web, Security, Boot и т.д.) MySQL PostgreSQL, PostGIS ...

8 дней назад

JCat, сервис размещения объявлений - метро Маяковская, Санкт-Петербург

35 000 руб.

...основными веб-технологиями: Php5+, jQuery, Html, Css, кроссбраузерная верстка. Большим плюсом будет знание Php7, JavaScript, AngularJs, Html5, MySql, Ajax. Java (Jse, Jee). Spring ответственность, аккуратность, работоспособность, креативность; самостоятельность ...

9 дней назад

Эшелон-Северо-Запад - метро Василеостровская, Санкт-Петербург

...корпоративные Web-приложения и мобильные приложения для Android и iOS. Приглашаем на работу разработчика со знаниями С++ / Qt / JavaScript / Java с перспективой развития в направлении Web-разработки. Будем рады пообщаться как с состоявшимися профессионалами, так и с ...

20 дней назад

Объединённая компания РУСАЛ - метро Парк Победы, Москва

...ОК РУСАЛ приглашает кандидатов на вакансию Java Программист. Обязанности: Разработка, сопровождение и доработка программного ... ...программирования; Знание основ XML, HTML, CSS, JavaScript, Ajax, SOAP, WSDL; Уверенные знания Java2 SE/Java 2 EE; ...

13 часов назад

Bell Integrator - Москва

...Написание тестов. Требования: Высокий уровень знаний core JavaScript; Знание TypeScript, React, ES6 Желательные требования: ... ...опыт работы с Ember, Vue.js или AngularJS, а так же знание Java, C# или любого другого «взрослого» объектно-ориентированного ...

26 дней назад

Финстарлабс - Румянцево, Москва

100 000 - 150 000 руб.

...Обязанности: 1. Разработка веб- и серверных приложений на Java с использованием Spring, Hibernate, AngularJS, Web Services, СУБД ... ...опыт разработки под Unix/Linux (желательно); 5. хорошее знание JavaScript; 6. опыт разработки используя AngularJS (ember.js, KnockoutJS ...

14 часов назад

Фролов Николай - Ростов-на-Дону

40 000 - 100 000 руб.

...Вакансия Java- программиста (или же C#-программиста, готового в краткие сроки перейти на Java) в одном из крупнейших предприятий южной столицы ... ..., Interbase, Firebird и др. Web-технологиями: html, javascript, jquery, spring framework. Системами контроля версий: Git ...

10 дней назад

Группа компаний «ИСЕРВ» - Чебоксары

2 001 руб./год

...ЖКХ, образовательных и медицинских учреждений приглашает программиста JavaScript (ReactJS) В настоящий момент, в связи с расширением территории ... ...запросов T-SQL; Знание какого-нибудь серверного языка (java, python, ruby, C#). Мы предлагаем: Возможность ...

26 дней назад

Металлинвестбанк - Белгород

150 000 руб.

...Разработка внутренней платформы развития бизнеса Требования: Знание Java, Spring; Владение SQL; Понимание процессов разработки веб-приложений, работы REST . Знание Javascript/ Jquery или аналогичных фронт-энд библиотек будет большим плюсом. (не ...

9 дней назад

Северсталь, Москва - Череповец

...стали; Участие в проектах внедрения системы Hybris в качестве Java- разработчика. Требования: Опыт работы (от года) с ... ...работы (от года) со Spring MVC; Опыт работы с HTML/CSS/ JavaScript (jQuery, Dojo, etc.); Опыт работы с веб-сервисами (REST/SOAP ...

10 дней назад

TEZ TOUR - Москва

150 000 руб.

...Разработка архитектуры платформенного решения и программных модулей на Java Разработка интеграционных приложений Разработка и ... ...Знание SQL Знание XML и JSON Базовые знания HTML, CSS, JavaScript Опыт работы – не менее 1 года Английский язык – на ...

18 дней назад

TANDEM - Екатеринбург

65 000 - 85 000 руб.

...Компания TANDEM приглашает программистов на позицию Middle Java developer "а в группу разработки. Работа на этой позиции предполагает освоение ... ...SQL. Знание HTML, опыт разработки с использованием JavaScript, понимание или опыт работы с технологией Ajax. Знакомство ...

10 дней назад

Центр Информационных Технологий - метро Динамо, Екатеринбург

60 000 руб.

...Компания Центр Информационных Технологий приглашает java -программистов для разработки региональн ой информационной медицинской системы ... ...ORM Опыт разработки web приложений (HTML, CSS, JavaScript) Опыт работы с СУБД Мы предлагаем: Работа в ...

Собрали список вопросов, ответы на которые должен знать не только каждый JavaScript разработчик, но и, пожалуй, любой программист.

Назовите две наиболее важные для JavaScript-разработчика парадигмы программирования?

JavaScript – мультипарадигмальный язык, поддерживающий императивное/процедурное программирования наряду с ООП и функциональным программированием. JS поддерживает ООП с прототипным наследованием.

Желательно упомянуть:

1. Прототипное наследование (также: прототипы, объектные ссылки)

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

Следует избегать:

Не иметь представления о парадигмах, не упомянуть прототипное ООП или функциональное программирование.

Что такое функциональное программирование?

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

Функциональное программирование – одна из основополагающих концепций JavaScript (один из двух столпов JS). Некоторые функциональные утилиты были добавлены в JavaScript в ES5.

Хорошо упомянуть:

1. Чистые функции / чистота функций

2. Избежание побочных эффектов

3. Простой состав функций

4. Примеры функциональных языков: Lisp, ML, Haskell, Erlang, Clojure, Elm, F Sharp, OCaml и т.д.

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

Следует избегать:

1. Отсутствие упоминаний чистых функций / избежание побочных эффектов

2. Не привести примеры функциональных языков

3. Не привести примеры функциональных фич JavaScript

В чем заключается разница между классовым и прототипным наследованием?

Классовое наследование: экземпляры наследуются от классов, создаются подклассовые отношения (иерархическая систематизация классов). Экземпляры реализуются через конструктор функции, через дескриптор new. Экземпляр класса может не содержать дескриптор class начиная с ES6.

Прототипное наследование: экземпляры наследуются напрямую от других объектов, реализуются через фабрики или Object.create() и экземпляры могут быть составлены из множества различных объектов для упрощения выборочного наследования. Прототипное наследование более простое и гибкое, нежели классовое.

Хорошо упомянуть:

1. Классы: тесные связи, иерархия

2. Прототипы: конкатенативное наследование, делегирование, функциональное наследование, композиция

Следует избегать:

Не указать на преимущества прототипного наследования перед классовым

Каковы плюсы и минусы функционального и объектно-ориентированного программирования?

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

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

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

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

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

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

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

Хорошо упомянуть:

1. Проблемы общих состояний, нежелательного поведения

2. Возможности ФП по радикальному упрощению кода программ

3. Разность в сложности изучения

4. Побочные эффекты и их влияние на надежность программ

5. Сложность изменения и общая хрупкость базы ОО кода в сравнении с таковой в функциональном стиле

Следует избегать:

Не упомянуть недостатки одного из подходов – каждый, кто сталкивался с одним из них, знает и о паре-другой недостатков

Когда классовое наследование – подходящий выбор?

Вопрос с подвохом. Правильный ответ – никогда. Композиция – более простой и гибкий подход, чем наследование классов.

Хорошо упомянуть

«…композиция объектов лучше, чем наследование классов»

Следует избегать:

Упоминание Rect Components. React.js использует дескриптор class, но не позволяет избежать подводных камней классового наследования. Вопреки популярным ответам, не нужно использовать class, чтобы пользоваться React. Такой ответ покажет не понимание как классов в JavaScript, так и Реакта.

Когда лучше использовать прототипное наследование?

Существует более, чем один тип прототипного наследования:

1. Делегирование (цепочка прототипов)

2. Конкатенация (миксины, Object.assign())

3. Функциональное наследование (не путать с функциональным программированием. Функция используется для создания замыкания для private/инкапсуляции)

Хороший ответ:

1. В ситуациях, когда модули или функциональное программирование не обеспечивают очевидного решения

2. Когда нужно собрать объект из нескольких источников

3. В любом случае, когда нужно применить наследование

Следует избегать:

1. Не знать, когда применяются прототипы

2. Не знать о миксинах или Object.assign()

Что значит «композиция объектов лучше, чем наследование классов»?

Это цитата из книги “Design Patterns: Elements of Reusable Object-Oriented Software”. Повторное использование кода должно достигаться за счет сборки малых единиц функциональности в новый объект, а не наследованием классов и созданием иерархий.

Хорошо упомянуть:

1. Избежание наследования и тесных связей

2. Избежание вытекающей из классического наследования проблемы «банан/мартышка» (нужен был банан – получили мартышку, держащую банан посреди джунглей)

Следует избегать:

Не назвать какую-то из упомянутых выше проблем. Не объяснить разницу между композицией и наследованием или не суметь рассказать об преимуществах композиции.

Что такое двусторонняя связь данных и однонаправленный поток данных и в чем разница между ними?

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

Однонаправленный поток данных означает, что только модель – источник истины. Изменения в интерфейсе запускают сообщения, которые сигнализируют пользователю о намерении модели (или «store» в терминах React). Смысл в том, что данные всегда идут в одном направлении, что облегчает понимание.

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

Хорошо упомянуть:

1. React – новый канонический пример однонаправленного потока данных, так что упоминание Реакта будет хорошей идеей. Cycle.js — еще одна популярная реализация однонаправленного потока данных.

2. Angular – популярный фреймворк, использующий двустороннюю привязку.

Следует избегать:

Непонимание этих концепций, неспособность объяснить разницу между ними.

Каковы плюсы и минусы монолитной архитектуры и микросервисов?

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

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

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

Минусы монолитного приложения: так как все компоненты тесно связаны друг с другом, по мере развития приложения, становится труднее его понимать, появляется много неочевидных зависимостей и побочных эффектов.

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

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

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

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

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

Хорошо упомянуть:

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

2. Практические различия микросервисов и монолитных приложений

Следует избегать:

1. Незнание различий архитектур

2. Незнание недостатков микросервисов

3. Недооценивать преимущества масштабирования микросервисов

Что такое асинхронное программирование и почему оно важно в JS?

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

Асинхронное программирование подразумевает, что когда требуется операция блокировки, запрос отправляется, и код продолжает работать без блокировки до ожидания результата. Когда ответ готов, запускается прерывание, это приводит к запуску обработчика событий и поток управления продолжается. Таким образом, один программный поток может обрабатывать множество параллельных операций.

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

Node.js по умолчанию асинхронен, по сути, сервер проводит все время в цикле, ожидая сетевой запрос.

В JavaScript это важно, так как естественно для интерфейсов и положительно сказывается на производительности сервера.

Хорошо упомянуть:

1. Значение блокировок, влияние на производительность

2. Понимание обработчиков и почему они важны для интерфейсов

Следует избегать:

1. Непонимание терминов синхронности и асинхронности

2. Неспособность определить последствия для производительности