Ресурсы для изучения Python на русском

  1. Если вы изучаете Python с самого нуля, то есть хороший курс, который стоило бы пройти на stepik.org.
  1. Также есть ещё один интересный интерактивный курс от pythontutor.ru
  1. Для тех кто предпочитает смотреть видео, то есть бесплатный курс для обучения Python на shultais.education
  1. Если Python не Ваш первый язык, то прекрасно подойдёт серия видеоуроков ниже. На канале CSC есть видео свежее, чем представленный плейлист, но мне лично заходит этот чувак. Также на этом канале есть видео и по другим языками программирования.
  1. Для практики своих навыков программирования есть Проект Эйлера. Решать задачи можно на любом языке программирования и хорошо подойдёт для прокачки базы и не только.

Процесс рендеринга веб-страницы

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

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

DOM (Document Object Model) и CSSOM (CSS Object Model)

Сервер доставляет фрагмент HTML-кода, который анализируется браузером, и создается дерево. Это дерево называется DOM. Кроме того, браузер также получает инструкции CSS, которые анализируются, и это генерирует другое дерево, называемое CSSOM.

Render Tree (Дерево рендера)

После завершения двух процессов синтаксического анализа и определения DOM и CSSOM браузер создает дерево рендера. Дерево рендера — это другое дерево, хранящееся внутри браузера и используемое для представления визуальных элементов. Элементы внутри <head> игнорируются, а также элементы, определенные с display: none. Однако стоит помнить, что элементы со свойством visibility: hidden по-прежнему являются частью дерева.

Как только рендер дерева завершен, браузер может выполнить процесс reflow (перекомпоновки) и repaint(перерисовки).

Reflow (перекомпоновка)

Процесс, используемый браузером для позиционирования элементов на экране, называется Reflow.

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

Repaint (перерисовка)

Также известна как redraw. Repaint — это имя процесса, используемого браузером, когда ему нужно обновить какой-то стиль, который не относится к макету. Другими словами стили, не связанные с положением, шириной или высотой. Примером может служить манипулирование цветом фона.

В заключении

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

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

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

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

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

compose = (fn1, fn2) => value => fn2(fn1(value))

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

add2AndSquare = (n) => square(add2(n))

Мы можем использовать функцию высшего порядка (higher order function), чтобы упорядочить их.

add2AndSquare = compose( add2, square)

Простая реализация compose будет выглядеть так:

compose = (f1, f2) => value => f2(f1(value));

Чтобы получить большую гибкость, мы можем использовать функцию reduceRight:

compose = (...fns) => (initialVal) => fns.reduceRight((val, fn) => fn(val), initialVal);

Примеры из разработки — добавления аутентификации, логирования или свойств контекста.

Вот несколько примеров, как можно использовать:

// example
const add2        = (n) => n + 2;
const times2      = (n) => n * 2;

const times2add2  = compose(add2, times2);
const add6        = compose(add2, add2, add2);

times2add2(2);  // 6
add2tiems2(2);  // 8
add6(2);        // 8

Вы можете подумать, что это не относится к фронтенду, но это также полезно в SPA (single page application). Например, вы можете добавить поведение к компоненту React, используя функции высшего порядка:

function logProps(InputComponent) {
  InputComponent.prototype.componentWillReceiveProps = function(nextProps) {
    console.log('Current props: ', this.props);
    console.log('Next props: ', nextProps);
  };
  return InputComponent;
}

// EnhancedComponent will log whenever props are received
const EnhancedComponent = logProps(InputComponent);

Заключение

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

Реализация compose присутствует во многих служебных библиотеках JavaScript (lodash, rambda и т. Д.).

Алгоритмы и структуры данных в JavaScript — Очереди

Очереди представляют собой набор элементов, который следует правилу first-in-first-out («первым пришел-первым вышел») — сокращенно FIFO. Очередь позволяет нам вставлять элементы с одного конца (называемого хвостом) и удалять их из очереди с другого конца (называемого головой).

Чтобы создать структуру данных очереди, давайте использовать фабричную функцию, которая возвращает очередь в виде объекта JavaScript. Внутри этой функции мы инициализируем пустой массив с именем queue. Очередь, которую мы создаем, также будет иметь различные свойства и методы внутри нее. Начнем с метода, который добавляет элементы в очередь только с одной стороны.

Здесь add() использует метод unshift для добавления элемента x в начало массива queue. Теперь нам нужно написать функцию, которая удаляет последний элемент из массива.

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

Теперь в соответствии с обычным поведением массива мы должны иметь элемент Iron Man с индексом 0, а Captain America — с индексом 1. Но поскольку marvelMovies — это очередь, Iron Man изначально был с индексом 0, и когда Captain America был добавлен в очередь, Iron Man был перемещен в индекс 1, а Captain America теперь находится в индексе 0. Удалить элементы из очереди просто. Все, что мы здесь делаем, это берем последний элемент в queue и извлекаем его.при помощи метода pop. Давайте добавим некоторую дополнительную функциональность в функцию, чтобы проверить следующий удаляемый элемент, длину очереди и, если очередь пуста или нет.

Подборка подкастов о фронтенде и не только


UnderJS Podcast:

Фронтенд Юность:



Пятиминутка React:

Пятиминутка Angular:

Прешоу «Сделайте мне красиво!»:

RadioJS:

SDCast:

Podlodka Podcast:

Сортировка пузырьком (bubble sort) на javascript

Bubble Sort является одним из наиболее широко обсуждаемых алгоритмов, просто из-за недостаточной эффективности сортировки массивов. Если массив уже отсортирован, Bubble Sort будет проходить через массив только один раз (с использованием концепции два ниже), однако в худшем случае это время выполнения O(n²), которое крайне неэффективно.

Когда мы рисуем скорость роста O(n²), мы видим, что по сравнению с другими алгоритмами сортировки, такими как сортировка слиянием, то есть O(n log n), он растет гораздо быстрее.

Не смотря на неэффективность Bubble Sort, все еще важно понять алгоритм и понять, почему он так плох.

Давайте углубимся в две концепции кодирования Bubble Sort.

Концепция 1

  • Итерация по массиву и проверка каждого элемента по следующему элементу в массиве.
  • Если текущий элемент больше, чем следующий элемент, меняйте их местами.
  • Если он не больше, переместите указатели вверх и сравните следующие два элемента.
  • Как только мы достигаем конца массива, мы знаем, что самый большой элемент находится в последней позиции.
  • Повторите этот процесс N раз, где N — длина массива, и каждый раз повторяйте до последнего отсортированного элемента.
Визуализация концепции 1

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

Концепция 2

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

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

Заключение

Bubble Sort — это один из самых неэффективных алгоритмов сортировки. В худшем случае нам придется сравнивать каждый элемент с каждым другим элементом в массиве, следовательно, сложность алгоритма будет O(n²).

Стандарт ES2020

Комитет TC39 недавно одобрил что войдёт в стандарт ECMAScript 2020 (широко известную как ES2020), которая содержит завершенный набор улучшений, входящий в язык JavaScript. Стандарт ES2020 должен быть рассмотрен и утвержден Генеральной ассамблеей ECMA в июне этого года. Большинство новых улучшений уже реализованы в браузерах и могут использоваться с помощью транспайлера Babel.

Спецификация ES2020 будет содержать:

  • matchAll — метод Strings, который создаёт итератор для всех объектов соответствия, сгенерированных глобальным регулярным выражением;
  • import () — синтаксис для асинхронного импорта модулей с динамическим спецификатором;
  • BigInt — для работы с произвольными целыми числами больших, чем 25^53 — 1 ;
  • Promise.allSettled — новый комбинатор Promise, который не замыкается;
  • globalThis — универсальный способ доступа к глобальному значению this;
  • выделенный экспорт * as ns from 'module' для использования внутри модулей;
  • повышена стандартизация for-in порядка перечисления;
  • import.meta — объект, заполненный хостом, доступный в модулях, который может содержать контекстную информацию о модуле;
  • и две новые функции синтаксиса для улучшения работы с «нулевыми» значениями (null или undefined): nullish coalescing — оператор выбора значений; optional chaining — позволяет считывать значение свойства, расположенного глубоко в цепочке связанных объектов, без необходимости явно проверять правильность каждой ссылки в цепочке.

Динамический импорт

Может использоваться для динамической загрузки модулей, созданных на этапе разделения кода в отдельные бандлы. Динамический импорт поддерживается большинством браузеров, за исключением IE11. С помощью import () разработчики могут импортировать динамически созданный модуль (moduleSpecifier = dir + 'my-math.mjs') асинхронно (вернётся Promise). Можно использовать по условию в любом месте кода:

import.meta

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

Когда этот модуль загружен, независимо от его местоположения, он загрузит одноуровневый файл hamsters.jpg и отобразит изображение. Размер изображения можно настроить с помощью элемента script, который используется для его импорта, например: <script type = "module" src = "path/to/hamster-displayer.mjs" data-size = "500"> </ script>

globalThis

Ключевое слово globalThis позволяет разработчикам писать код ECMAScript, который обращается к глобальному объекту, избавляя от необходимости использовать window, self, global соответственно в браузере, воркере, Node.js и работая с другими средами.

export * as ns from "mod"

Новый синтаксис экспорта (export * as ns from "mod") добавляет новую форму экспорта, из которой экспортируется экзотический объект пространства имен другого модуля в качестве экспортированного имени другого, заполняя сценарий использования, аналогичный сценариям использования для существующего экспорта из форм.

Promise.allSettled()

Promise.allSettled() завершает существующие Promise.all() и Promise.race() ECMAScript ES2015 и обрабатывает случай, когда все промисы выполняются независимо от результата (выполненного или отклоненного), позволяя писать код следующим образом:

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

Optional chaining (a? .B) и nullish coalescing (a ?? b)

Optional chaining (a? .B) и nullish coalescing (a ?? b) поддерживаются в Babel (начиная с Babel 7.0); Edge, Chrome и Firefox вечнозеленые браузеры; а также TypeScript 3.7+. Обе функции допускают замыкания, если значение для доступа / вызова равно нулю. Например, пусть x = foo?.Bar.baz(); кратко заменяет:

BigInt()

В то время как 2 ^ 53 + 1 ошибочно оценивается как 9007199254740992 (число нечетное, поэтому не может заканчиваться цифрой 2), следующие 2n ** 53n + 1n правильно оцениваются как 9007199254740993n. Подобные ограничения являются одной из причин того, что JSON API в Twitter возвращает идентификаторы твитов в виде строк, а не буквальных чисел. BigInt поддерживается в большинстве современных браузеров (включая Firefox 68+, Chrome 67+) и может работать в других браузерах.

String.matchAll

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


TC39 — это группа разработчиков, разработчиков, разработчиков и других разработчиков JavaScript, которые сотрудничают с сообществом для поддержки и развития спецификации JavaScript (формально, ECMAScript). TC39 включает в себя всех основных поставщиков браузеров. Каждое предложение для функции ECMAScript проходит следующие стадии зрелости:

  • Этап 0: Strawman;
  • Этап 1: Предложение;
  • Этап 2: Черновик;
  • Этап 3: Кандидат;
  • Этап 4: Закончено.

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

ECMAScript 2020 — одиннадцатое издание Спецификации языка ECMAScript. Со времени публикации первого издания в 1997 году ECMAScript стал одним из наиболее широко используемых в мире языков программирования общего назначения.

Что такое Nullish Coalescing

Нулевой оператор объединения (??) — это логический оператор, который возвращает свой правый операнд, когда его левый операнд равен null или undefined, и в противном случае возвращает свой левый операнд.

В отличие от логического оператора OR (||), левый операнд возвращается, если это ложное значение, которое не является null или undefined. Другими словами, если вы используете ||, чтобы предоставить какое-либо значение по умолчанию другой переменной foo, вы можете столкнуться с неожиданным поведением, если вы считаете некоторые ложные значения пригодными для использования (например, " " или 0).

Пример: