html, css, js: Переводы

Заметки про angular

Отличие контроллеров от сервисов

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

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

30 января   angular

Переосмысление JavaScript: Конец цикла For

Автор: https://hackernoon.com/@joelthoms
Оригинал статьи: https://hackernoon.com/rethinking-javascript-death-of-the-for-loop-c431564c84a8#.24xq0khm1

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

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

В любом случае, какая проблема у цикла for?

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

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

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

Далее, Я бы хотел быстро поговорить о побочных эффектах. Эти слова звучат просто ужасно, побочные эффекты. Тьфу. Вы бы хотели, чтобы у вашей программы были побочные эффекты? Нет, Я бы не хотел, чтобы у моих программ были побочные эффекты.

Но что такое эти самые побочные эффекты?

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

Побочные эффекты — влиятельны, но с большой силой приходит большая ответственность.

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

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


const cats = [
  { name: 'Mojo',    months: 84 },
  { name: 'Mao-Mao', months: 34 },
  { name: 'Waffles', months: 4 },
  { name: 'Pickles', months: 6 }
]
var kittens = []
// typical poorly written `for loop`
for (var i = 0; i < cats.length; i++) {
  if (cats[i].months < 7) {
    kittens.push(cats[i].name)
  }
}
console.log(kittens)

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

Первое, что я хочу сделать, извлечь if в его собственную функцию.

const isKitten = cat => cat.months < 7
var kittens = []
for (var i = 0; i < cats.length; i++) {
  if (isKitten(cats[i])) {
    kittens.push(cats[i].name)
  }
}

Хорошая практика, в самом начале вынести if. Поменять фильтр от “less than 7 months” к “is a kitten” большое дело. Теперь, когда вы читаете код, цель становится яснее. Почему мы получаем кошек до 7 месяцев? Это совсем не понятно. Мы ведь хотели найти котят, так пусть наш код сделает это!

Другая польза в том, что isKitten сейчас переиспользованный и мы это знаем,

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

Следующее изменение, это извлечением преобразования (или mapping) из объекта типа cat к name. Это изменение будет иметь больше смысла позже, поэтому сейчас вам нужно просто поверить мне.

const isKitten = cat => cat.months < 7
const getName = cat => cat.name
var kittens = []
for (var i = 0; i < cats.length; i++) {
  if (isKitten(cats[i])) {
    kittens.push(getName(cats[i]))
  }
}

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

const isKitten = cat => cat.months < 7
const getName = cat => cat.name
const kittens =
  cats.filter(isKitten)
      .map(getName)

Также обратите внимание, что мы убрали kittens.push(...). Нет больше изменяемого состояния и var.

Код который использует const (вместо var и let) чертовски сексуален

Для полного раскрытия темы, мы могли бы использовать const все время, потому что const не изменяет сам объект (подробнее об этом в другой раз). Но, эй, это же придуманный пример, дайте мне немного поблажки!

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

А теперь все вместе:

const isKitten = cat => cat.months < 7
const getName = cat => cat.name
const getKittenNames = cats =>
  cats.filter(isKitten)
      .map(getName)
const cats = [
  { name: 'Mojo',    months: 84 },
  { name: 'Mao-Mao', months: 34 },
  { name: 'Waffles', months: 4 },
  { name: 'Pickles', months: 6 }
]
const kittens = getKittenNames(cats)
console.log(kittens)

В дополнении, как бы вы в дальнейшем декомпозировали эти функции? Подумайте о «less than» или свойстве «name», «map» или «filter». И еще как дополнение, вы могли бы исследовать состав функции.

25 января   javascript   перевод