progway — программирование, IT
2.65K subscribers
25 photos
1 video
246 links
Чат: @prog_way_chat

Разборы вопросов и задач с собеседований, мысли, полезные материалы и просто вещи, что мне интересны из мира IT

Полезности и навигация в закрепе

По всем вопросам: @denisputnov
Download Telegram
MongoDB - ультимативное решение для ваших проектов.

Давно хотел написать именно о монго. Люблю и обожаю её. MongoDB - система управления базами данных, основой для которой является документноориентированная модель, где каждый документ - JSON. Как уже стало, думаю, понятно, MongoDB - NoSQL база данных, обычное key/value хранилище, которое не требует описания таблиц и тому подобных ритуалов.

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

Если для многих иерархия SQL СУБД уже знакома (многие знают, что такое база данных, что такое таблица, колонка и тд.), то в отношении MongoDB люди иногда встают в ступор. Также не для всех понятно что такое документноориентированная модель, так что предлагаю разобрать местную иерархию:

База данных - место хранения нескольких коллекций. Это, так называемый, контейнер для наших коллекций.

Коллекция - место хранения нескольких документов. Аналог из SQL мира - таблица.

Документ - JSON. Это обычный объект (или, если угодно, словарь), который представляет из себя пары key/value.

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

[
{
"_id": ...,
"name": "Denis",
"email": "email@email.com",
"isSubscribed": true
},
{
"_id": ...,
"code": 200,
"status": "success"
}
]

Как вы можете заметить, структура совершенно разная. Но стоит заметить и то, что в каждом документе присутствует поле "_id". И на самом деле это не мое желание. Это стандартное поле, которое будет в каждом документе вне зависимости от вашего желания. Если вы не зададите _id самостоятельно, то ему автоматически присвоится значение экземпляра класса ObjectId. Выглядит это примерно так:
ObjectId(4af19ef1109d)

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

Тогда почему же MongoDB так популярна и так часто используется? Простота. Приложение с использованием MongoDB можно развернуть за рекордно короткие сроки. Всё можно изменить в процессе, а при необходимости масштабироваться или переехать на SQL. С монго нас ничего не ограничивает (кроме малой функциональности, конечно). Это прекрасный вариант для простых и не очень приложений с коротким жизненным циклом, для прототипирования и тому подобных проектов, что не подразумевают многолетней поддержки или сложной обработки данных.

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

Из-за этой особенности мы используем монго в разработке ботов. Для ботов не нужна тяжёлая обработка данных, а бесплатность и доступ по сети делают MongoDB действительно ультимативным решением. Запускаем скрипт бота на хероку, коннектимся к Mongo Cloud и получаем бота, работающего полностью бесплатно, да и к тому же стабильно и без проблем.

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

Вот такие дела. Спасибо за прочтение и за интерес к каналу, для меня это важно ❤️

#github #web #useful #theory
Насчёт отдыха и выгорания.

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

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

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

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

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

Когда я стал замечать это, то, как мне кажется, все стало лучше. Суть в том, чтобы не допустить достижения критической точки и сбрасывать усталость постепенно. На каждом сработает индивидуально. У кого-то продуктивность понизится, а у кого-то, наоборот, повысится. И способы снятия усталости могут быть диаметрально разные для каждого человека. Может это спорт, может какое-то хобби, а может любимый человек, как вариант. Главное тут - это регулярная смена деятельности и разнообразие в делах.

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

Достаточно очевидные мысли, но понимать самому и слышать подтверждение извне — разные вещи. Как-то так.

#blog
Что такое синхронный и асинхронный код.

Я пост написал, а он слишком большой, так что этот пост про асинхронщину - лишь часть будущей серии постов, скоро будет. Тут мы разберём синхронный и асинхронный код и сделаем это на примере великого и ужасного JavaScript, потому что я всё же выбрал этот язык как свою основную технологию уже давно, даже относительно создания канала. Я кое-как знаю Python, но больше не вижу смысла проталкивать это направление на канале. Итак, слишком много отступлений, переходим к делу.

Что же такое синхронный и асинхронный код в однопоточных языках (типа JavaScript или Python):

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

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

Но из-за асинхронного кода могут наблюдаться подобные варианты исполнения кода:

// code
setTimeout(() => {
console.log("Сообщение сразу")
}, 1500)

console.log("Сообщение через 1500мс")

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

// console out
Сообщение через 1500мс
Сообщение сразу

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

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

В общем, продолжение следует. И спасибо за прочтение спустя 40 дней с прошлого поста. Вы золото ❤️

#web #javascript
👍2
Обработка асинхронного кода.

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

В JavaScript мы имеем несколько возможных вариантов обработки асинхронного кода:
- асинхронные callback'и,
- промисы,
- синтаксис async/await.

Callback'и в этом посте мы не будем рассматривать. Остаются промисы и синтаксис async/await, которые идет, конечно, отдельными пунктами, но вообще-то стоит понимать, что в JavaScript операторы async/await - это не более чем синтаксический сахар, надстройка над промисами. Отсюда следует и то, что промисы и новый синтаксис могут использоваться совместно.

Перепишем код с использованием промиса:

new Promise((resolve, reject) => {
setTimeout(() => {
resolve(console.log("Сообщение через 1500 мс"))
}, 1500)
}).then(() => {
console.log("Второе сообщение");
})


Что тут происходит?
1. Мы создаём новый Promise через конструктор.
2. Внутрь конструктора мы подаём функцию, которая принимает в себя 2 параметра: resolve и reject. Это две функции. Особенно углублять не будем, но когда вызывается resolve - промис считается выполненным, а когда reject - выбрасывается ошибка.
3. Метод then вызывается от нашего промиса, принимает в себя так же функцию (которая в свою очередь так же может принимать в себя параметры, но в этом примере они не нужны). Эта функция из метода then гарантированно выполнится после промиса.

И такой код даст нам ожидаемый результат:

// console out
Сообщение через 1500 мс
Второе сообщение


И таких методов then может быть много в цепочку:

new Promise(...).then(...).then(...).then(...) ... .catch(...)


Тут вы можете заметить ещё и метод catch. Он нам нужен для обработки ошибок в промисах.

Если совсем кратко, то вот так можно описать промисы. Они необходимы для понимания того, как работает синтаксис async/await в JavaScript. И этот синтаксис не применим к нашему примеру в чистом виде, потому что функция setTimeout не возвращает Promise, а, как я и сказал выше, без промисов async/await не работает. Но промис возвращает, например, fetch запрос. Fetch позволяет нам делать HTTP запросы и позвращает промис.

Попробуем:

async function getDataFromServer() {
// сделаем запрос
const response = await fetch('https://jsonplaceholder.typicode.com/todos')

// обработаем данные
const data = await response.json()

return data
}


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

async function getDataFromServer() {
// сделаем запрос и преобразуем полученные данные
return await fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
}


По моему, получается лаконичнее.

Примерно так. Не знаю как часто будут новые посты, но они точно будут. Надеюсь будет почаще.

#javascript #web
👍1
О переходе.

Обычный пост из серии блога, где я хочу объяснить почему на канале теперь будет JavaScript (не только он).

Я думаю, многим не понравится, что с Python я резко и без особых предпосылок перескочил на JavaScript. Как говорится, ничего не предвещало беды, но пришло откуда не ждали.

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

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

Почему должно быть всё равно?
Большинство концептов, существующих в программировании, можно рассмотреть обособленно от конкретного языка. В современном мире различия не так критичны, поэтому огромная часть теории актуальна от языка к языку. Я не знаю Java или С#, но практически все книги по архитектуре приложений и тому подобным темам я прочитал с примерами на этих двух языках. И если отбросить всю предвзятую ненависть к JavaScript, которая присуща комьюнити сегодня, то на каком бы языке теория не была описана - при желании всё легко читается и понимается. Даже на JavaScript.

#blog
👍2
Что такое область видимости переменных

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

Чтож, область видимости переменных в вашей программе - это та область, откуда переменная доступна. И тут нужно понимать, что видимость переменных распространяется исключительно наследовательным путем (в виде дерева, графа). Это значит, что переменные из области родителя доступны в детях, но не наоборот. Что за дети и родители?
Рассмотрим пример:

const fib = [ 1, 1, 2, 3 ]

const sayHello = (name) => {
const surname = "Putnov"
console.log(`Hello, ${name} ${surname}`)
}

{
const channel = {
name: "progway",
theme: "blog"
}
}

fib // [ 1, 1, 2, 3 ]
surname // Error: is not defined
channel // Error: is not defined


В данном случае мы видим, как области видимости создаются внутри файла.
Области видимости тут:
— весь файл
— функция sayHello
— область внутри { } с объявлением объекта channel

Если совсем упростить, то можно сказать, что область видимости в JavaScript создаётся внутри { фигурных скобок }. Если понять этот концепт тут, то в нормальных языках всё будет ещё проще.

Внизу мы пытаемся обратиться к переменным. Массив чисел Фибоначчи доступен, а вот переменные surname и channel недоступны. Это из-за того, что объявлены они в дочерних областях видимости. В обратную сторону доступ сработает, например: 

const identificators = [11, 24, 93, 8]

function foo() {
console.log(identificators[0]) // 11
}

foo()

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

Но, JavaScript имеет разные спецификации синтаксиса и в примерах выше я использовал ES6 синтаксис. При объявлении переменной через let и const переменная не покидает пределы своей области видимости.
А теперь попробуем использовать var:

{
var name = "progway"
const age = "less than 1 year"
}

name // "progway"
age // Error: is not defined

Вот так вот неожиданно переменная, объявленная через ключевое слово var появляется в глобальной области видимости, чего, например, с const не происходит.

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

Спасибо за прочтение, это правда важно для меня.

#javascript #theory
Замыкания

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

Замыкание с точки зрения теории — это способность функции запомнить своё окружение (ссылки на переменные) в момент вызова. Это такой способ манипуляции областями видимости, который позволяет «замкнуть» переменную внутри тела функции. При помощи такой манипуляции мы можем расширить функционал обычных функций путём создания новых функций с замкнутыми в них переменными. На теории всё вообще не понятно, хотя я правда старался. Рассмотрим пример:

function sayHello(name) {
function wrapped() {
console.log(`Привет, ${name}`)
}
return wrapped
}

// создаем много функций на базе одной
const helloDenis = sayHello("Денис")
const helloKate = sayHello("Катя")
const helloMax = sayHello("Макс")

helloDenis() // Привет, Денис
helloKate() // Привет, Катя
helloMax() // Привет, Макс


Переменная name является замкнутой.

Каким образом мы добиваемся замыкания? В теле функции sayHello мы объявляем локальную функцию, которая остается доступной только внутри тела этой самой функции (из-за особенностей областей видимости). Возвращаем эту функцию. А у этой функции есть доступ к переменной name. Значение переменной при вызове sayHello замыкается, так как при каждом вызове функции sayHello внутри нее создается своя локальная переменная name, никак не зависящая от вызова этой функции снова. На практике должно быть понятнее.

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

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

#javascript #theory
MVC на пальцах

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

MVC — это паттерн проектирования. Аббревиатура от слов Model, View, Controller. И, несмотря на такую большую распространненность и важность в целом, всё максимально просто. Суть заключается в том, что приложение разбивается на 3 блока, каждый из которых имеет свои функции. Три этих блока, соответственно, — модель, представление и контроллер.

Рассмотрим каждый из блоков отдельно:
Модель — это блок, который отвечает за данные нашего приложения, и, по сути, во многом определяет его. Этот блок кода определяет данные и способы взаимодействия с ними.
Представление — блок, который отвечает исключительно за представление наших данных. Этот блок кода отвечает только за то как будет выглядеть наше приложение и не несет в себе никакой бизнес-логики.
Контроллер — блок, который организовывает взаимодействие модели и представления. В контроллере мы вешаем прослушку событий, взаимодействуем с данными и в целом организуем в этом блоке всю бизнес-логику нашего приложения.

На примере,
Ноутбук: монитор (представление), память (модель), и процессор (контроллер)
Ресторан: вкусный кофе (представление), официант (контроллер), и повар (модель)

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

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

Спасибо за прочтение, это важно ❤️

#theory #patterns
1
Итерирование по сущностям: map

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

Функция/метод map реализована во многих ныне используемых языках программирования. Скажем так, реализация функций map, reduce и filter дает языку хоть какое-то право называться функционально-поддерживаемым. Так вот, одна из этих функций — map, используется для перебора массива. В JavaScript это метод класса Array.

a = [1, 2, 3].map(callback, context)

Самое важное про map:
- метод массива
- принимает в себя callback функцию и контекст
- возвращает новый массив

Метод map проитерируется по всему массиву и применит callback функцию к каждому из элементов массива с указанным контекстом context. Тут важно понимать, что контекст — не обязательный параметр. Чаще всего метод применяется без него.

Что за функцию мы применяем? Это обычная callback функция, которая принимает в себя 3 параметра: элемент, его индекс и копию итерируемого массива:

a = [1, 2, 3].map((element, index, array) => {
console.log(`${element} is the ${index} element of ${array}`)
})

// Output:
1 is the 0 element of 1,2,3
2 is the 1 element of 1,2,3
3 is the 2 element of 1,2,3

Но только есть один нюанс:

console.log(a)

// output
[ undefined, undefined, undefined ]


Дело в том, что наша callback функция не возвращает никакого значения. Чтобы получить новый массив необходимо вернуть новое значение. Разберем тривиальный пример:

a = [1, 2, 3].map(element => element ** 2)
console.log(a)

// output
[1, 4, 9]


Теперь мы получили квадраты от значений массива.

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

#javascript #web #theory #useful
А в чём все таки разница между var, let и const?

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

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

function foo() {
var i = 0
}
console.log(i) // i is not defined


Область видимости переменных, объявленных через let и const ещё уже — она блочная:

if (true) {
var i = 0
let k = 0
}

console.log(i) // 0
console.log(k) // k is not defined


То есть переменные, объявленные через let и const не доступны уже за пределами блока.
Блок — область { между фигурными скобками }

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

Все остальные различия — вторичны. То, что описал здесь я — главный смысл введения новых способов объявления переменных. И спасибо за прочтение, это правда важно.

#javascript #web #theory
IIFE

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

В прошлом посте я уже рассказал о том что такое блочная область видимости, но иногда речь заходит о поддержке старых версий EcmaScript, поддержке старых браузеров ( что сейчас уже пусть и актуально, но не так сильно, как раньше ). В таких случаях мы не можем использовать let и const, а следовательно и блочная область видимости нам недоступна. В таких случаях используют IIFE.

IIFE Immediately-invoked Function Expression — или мгновенно вызываемое функциональное выражение. Это определенный синтаксический прием, который позволяет сразу объявить и вызвать функцию в указанном месте. Таким образом мы создаем костыльный аналог блочной области видимости, который ограничено областью видимости этого функционального выражения. Тут рассмотрим пример.

Допустим, нам нужно проитерироваться по массиву и вывести его значения через какой-то промежуток времени:
var array = [1, 2, 3, 4, 5]

for (var i = 0; i < array.length; i++) {
setTimeout(() => {
console.log(array[i])
}, 500)
}

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

На самом деле вывод такой:
undefined
undefined
undefined
undefined
undefined

Что? Почему? Всё из-за особенностей объявления переменной через var. Итерация проходит менее чем за 500мс. На моём ПК она проходит всего за 2мс. Значение переменной i в начале последнего прохода достигает значения 4, а в конце прохода становится равной 5 ( т.к. выражение i++ выполняется после отрабатывания всего тела for )

Функция setTimeout никак не блокирует поток, поэтому мы быстро итерируемся, получаем i = 5, а через еще 498мс обращаемся к array[5], но такого элемента нет, максимум 4, нумерация же с нуля. При этом с let всё работает отлично

И когда нужно получить ожидаемый вывод, но нельзя использовать новый синтаксис, используется IIFE. Выглядят они так:
(function(локальное название переменных) {
тело функции
})(переменные на вход)


Перепишем вышеописанный пример с использованием IIFE:
for (var i = 0; i < array.length; i++) {
(function(i) {
setTimeout(() => {
console.log(array[i])
}, 500)
})(i)
}

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

В итоге получаем ожидаемый вывод:  
1
2
3
4
5

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

И на этом всё, спасибо за прочтение. Если вам не лень, то поделитесь каналом с друзьями. Аудитория лишней точно не бывает. Люблю.

#javascript #web #theory
Итерирование по сущностям: reduce

Уже чуть ранее мы разбирали что такое метод map для массива, а теперь пополним список методом reduce.

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

Допустим, у нас есть массив чисел:

const numbers = [1,2,3,4,5,6,7,8,9]

Если мы не знаем что такое reduce, то сумму чисел массива мы скорее всего найдём так:

let sum = 0
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i]
}

4 строки. А c помощью reduce сделаем в одну:

const sum = numbers.reduce((sum, current) => sum + current)

Казалось бы, да какая разница? Получим мы одно и то же, только разное количество строк потратим? Да всё равно.

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

Полная сигнатура:

array.reduce(reducer, initialValue = 0)

reducer = (accumulator = initialValue, currentValie, index, array) => ...

На этом всё. Спасибо за прочтение. 

#javascript #web #theory #useful
Сессия в унике негативно влияет на канал. Пост завтра в 17:00
Что такое callback функция

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

Сегодня обсудим базовое понятие в теории языков, которое актуально везде.
Callback функция — это функция, которая должна быть вызвана после выполнения чего-то (чаще всего другой функции). Таким образом мы можем контролировать порядок вызова функции.

Функция высшего порядка — функция, которая принимает в качестве аргумента другую функцию и/или возвращает новую функцию.

Чаще всего callback функции рассматриваются вместе с понятием функций высшего порядка. Оно и понятно. В более глобальном смысле, callback функция — функция, переданная в другую функцию в качестве аргумента, позже вызванная. Сначала в стеке вызова появится функция высшего порядка, а потом наш callback. Говорящее название — функция обратного вызова.

Рассмотрим на примере:

const logSuccess = () => console.log("Запрос выполнен успешно")

const fetchData = async (uri, callback) => {
const data = await fetch(uri)
... // обрабатываем результат запроса
callback() <-- вызов callback'а
return json
}

 
Таким образом после выполнения запроса мы можем выполнить любое действие. Это действие будет динамичным, будет определено в результате обработки логики приложения. Нам не нужно заранее определять callback, мы можем просто подать необходимую функцию в вызов и выполнить любое действие после. Как-то так.

Надеюсь было полезно. Спасибо за прочтение.

#javascript #theory
Деструктуризация JavaScript

Как вы справляетесь с ситуацией, когда из объекта нужно сохранить определенную переменную?
Самым удобным способом является деструктуризация. Это синтаксис, когда мы в одну строку создаем несколько переменных из какого-либо объекта.


const json = {
name: "Denis",
surname: "Putnov",
age: 19,
email: "email@email.com",
adress: {
city: "Voronezh",
country: "Russia",
},
username: "grnbows"
}

Допустим, у нас есть такой json, пришедший нам с сервера. Реализуем функцию приветствия:

const sayHi = (person) =>
console.log(`Hi ${person.name} from ${person.adress.country}`)


Работает отменно и выводит нужное сообщение. Но код выглядит не очень красиво.

Перепишем функцию и воспользуемся деструктуризацией:

const sayHi = (person) => {
const {name, adress: {country}} = person

console.log(`Hi ${name} from ${country}`)
}


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

const sayHi = ({ name, adress: { country } }) =>
console.log(`Hi ${name} from ${country}`)


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

На этом у меня всё. Спасибо за прочтение.

#javascript
JavaScript: в чем разница null и undefined?

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

1. Основное отличие: null присваивается только явно самим разработчиком, в то время как undefined интерпретатор может присвоить самостоятельно.

undefined присваивается к переменным, для которых значение неопределено, например:

var name;
console.log(name) // undefined
name = "Denis"
console.log(name) // Denis


null присваивается к переменным только явно, то есть:

var name = null


2. Разное поведение при применении оператора typeof

typeof null // 'object'
typeof undefined // 'undefined'


Причем, на самом деле, и null и undefined являются примитивами. Но null имеет type 'object' по историческим причинам. Связано это с проблемами обратной совместимости. Чтобы не ломать уже написанный код, уже с очень давнего времени в JavaScript существует этот костыль.

Это два отличия, назвав которые вам со 100% вероятностью засчитают правильный ответ на вопрос. 

Спасибо за прочтение, вы классные.

#javascript
🔥1
Function expression vs Function declaration.

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

Function declaration:

function sum(a, b) {
return a + b
}


Function expression:

const sum = function sum(a, b) { return a + b }

или с использованием синтаксиса стрелочной функции:

const sum = (a, b) => a + b


Функционал одинаковый, все функции вернут одинаковый результат при одинаковых входных данных. Но есть разница. Все функции, объявленные через Function declaration инициализируются еще до выполнения кода. Это значит, что нам не важно где функция объявлена. Вызвать её можно в любой момент, даже до фактического объявления в коде:

sum(2, 7) // 9

function sum(a, b) {
return a + b
}


С функциями объявленными через Function expression так не получится, ведь механизм объявления такой функции идентичен механизму объявления переменной:


sum(2, 7) // ReferenceError: sum is not defined

const sum = function sum(a, b) { return a + b }


В этом основная разница 🙂
Спасибо за прочтение, это важно для меня.

#javascript
1
Infinity в JavaScript

В JavaScript существуют специальные значения: Infinity и -Infinity. Эти значения используются как границы в алгоритмах как бесконечно большое и бесконечно малое значение соответственно.

Получить такие значения можно явно:

let a = Infinity

Или в некоторых случаях, например:

1 / 0 // Infinity
-1 / 0 // -Infinity


В целом, особо тут обсудить больше нечего. Пост скорее просветительский, из разряда «глянь что могу».
Спасибо за прочтение.

#javascript
Сделал на реакте блог, просто от безделья. Там некоторые посты с канала. Если кому-то интересно как канал мог бы выглядеть в форме сайта, то пощупать можно тут.

Страница проекта на guthub: markdown-github-blog

#blog
👍4
Что такое this

Часто понятие контекста this у новичков и не только вызывает массу вопросов.

Если максимально просто, то контекст — это объект. Это первый пункт, который необходимо запомнить. Контекст — это всегда объект, которому принадлежит исполнение кода. Что это значит?
Разберем на примере браузера:
Допустим, что есть функция foo()

function foo() {
console.log(this === window)
}

Это весь наш код.  Если мы вызовем эту функцию в глобальной области видимости, то увидим в консоли значение true. Это происходит потому что наша функция вызывается относительно глобального объекта window. Вызов принадлежит объекту window. Более того,
this.hasOwnPropery('sayHi') === true

Созданная нами функция является методом внутри глобального объекта. Поэтому ключевое слово this в этом случае действительно равно объекту window.

Давайте попробуем создать класс с методом, который покажет нам контекст объекта, инстанса класса:

class Bar {
constructor(number) {
this.number = number
this.name = 'denis'
}

showThis() {
console.log(this)
}
}

const bar = new Bar(5)
bar.showThis()


Достаточно простой код. Мы создаем класс Bar, в методе constructor объявляем контекст нашего класса. При вызове метода showThis мы увидим ожидаемый объект:

{
name: "denis",
number: 5
}


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

Контекст — ближайший вышестоящий объект, который управляет вызовом кода.
Контекст динамичен.
Контекст доступен по ключевому слову this.

На самом деле, this — это лишь ссылка на запись в памяти, которая указывает на контекст.  А если это всего лишь ссылка, то значит мы можем управлять контекстом, вау! На управлении контекстом реализованы несчетное количество паттернов и концепций. Об управлении контекстом мы поговорим позже, а за управление контекстом отвечают методы call,apply и bind. Их нужно знать и уметь применять, ждите новый пост.

Из нюансов:
1. Глобальный контекст разный на разных платформах: в браузере это объект window, в nodejs это объект global
2. Контекст разный в зависимости от режима работы: в режиме "use strict;" или без него. О том, что такое "use strict;" я тоже скоро расскажу.
3. Стрелочные функции не имеют собственного контекста. Их контекст всегда указывает на глобальный объект.
4. В DOM-API ключевое слово this указывает на объект event.currentTarget(). Для понимание этого пункта рассмотрите код ниже.


<button onclick="console.log(this.innerHTML)">
Текст внутри кнопки
</button>

При нажатии на кнопку в консоли увидим сообщение "Текст внутри кнопки".
Занятно, но с современными фреймворками, наверное, бесполезно.

На этом всё. Спасибо за прочтение, это важно для меня.

#javascript #web #theory