Дэн Щербаков ⚛️
95 subscribers
20 photos
49 links
Канал для фронтенд-разработчиков о том, как развиваться и увеличивать зарплату.

Senior Frontend Developer с 6 годами опыта. За этот период увеличил зарплату почти в 7 раз.

Начинайте тут: https://yangx.top/code_lab/280
加入频道
Функциональное:

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

- Предикаты - это функции, возвращающие true или false.

- Компараторы - функции, возвращающие диапазон значений: -1, 0, 1

- Аппликативы - функции, которые принимают данные и другие функции, после чего применяют эти функции к данным.
Примеры - методы массивов .map, .reduce и другие.
PHP:

Есть четыре схожих метода подключения внешних файлов:

include
include_once
require
require_once

Различия:
1. require прекращает выполнение скрипта, если подключаемый файл отсутствует, include - нет;
2. постфикс once позволяет включить файл только один раз, сколько бы вызовов не осуществлялось - это удобно, когда во включаемом файле имеется определение фукнций, так как повторное их определение приведёт к ошибке. То есть, это дополнительный уровень устойчивости: случайное подключение несколько раз одного файла будет проигнорировано.

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

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

1. На странице, с которой происходит редирект, продолжается выполнение кода. Если нужно прекратить это - после header() вызываем die или exit.
2. Задержка редиректа делается через аргумент header( refresh: <значение> ).
3. Для редиректа на локальные файлы не обязательно писать полный URL - хватит пути к файлу в директории.
4. Заголовки нужно отправлять до вывода любого контента на страницы.
5. Редирект на шаблон 404 и установка кода ответа тоже делается через header:

<? header("HTTTP/1.0 404 Not Found") ?>
PHP - заметки по ООП:

- Три поля видимости значений и методов:
public
protected
private
Они записываются перед названиями сущностей, и назначение их достаточно понятно из названий. Protected отличается от Private тем, что дает более широкий доступ к защищенному свойству - из подкласса. Однако защищенные свойства можно вызывать с помощью методов.

- Конструктор в PHP выглядит как метод __conctruct. Он вызывается при создании экземпляра класса автоматически и принимает аргументы, переопределяющие дефолтные значения. Благодаря нему можно сократить код, передавая значения не присвоением "ключ-значение" в программе, а через скобки при объявлении нового экземпляра.

Плохо:
$serial_first = new Eva();
$serial_first -> $height = 12;
$serial_first -> $weapon = 'knife';
$serial_first -> $autonomy_min = 30;

Хорошо:
$serial_first = new Eva(12, 'knife', 30)

Можно использовать аналогично конструктору обычную функцию, но это не pest practice.

- По аналогии с конструктором есть __destruct - метод, автоматически вызываемый при удалении всех ссылок на объект в коде (и, следовательно, самого объекта). На практике он используется для управления памятью и выноса связанных с уничтожением класса процедур в автоматический метод, чтобы не думать о них при написании остального содержимого.
PHP - мелочи:

- Для вывода сложных конструкций, а-ля вызов свойства или метода объекта в PHP, недостаточно двойных кавычек. Используется фигурный синтаксис, как в ES6.
- This записывается через знак доллара, и в целом работает как аналог из JS.
- Static - поле, указывающее, что метод или свойство могут быть использованы в контексте самого класса. То есть, для работы с ними не нужно создавать экземпляр объекта класса: просто подключаем класс и вызываем методы. Одно из преимуществ подхода - экономия памяти.
- Для работы со статическими методами классов пользуются вместо this конструкцией "self:: $staticVariableName".
- Cоответственно, self указывает на класс, а this - на экземпляр класса.
- Статические методы тоже выводятся через ::.
- Есть подход, полностью основанный на статических свойствах и методах. Его иногда называют "Классово-ориентированное программирование".
- В PHP есть константы. Записываются они, как и в JS, через const, и не требуют доллара перед именем. Они пишутся в верхнем регистре.
- Оператор .= это сокращенная конкатенация:
$a .= $b // $a = $a . $b
PHP - наследование:

- Написание __construct в дочернем классе переопределяет унаследованный конструктор.
Первый путь решения - дублировать родительский конструктор.
Второй, более соответствующий принципам ООП - вызов конструктора родителя через parent::__construct(аргументы родителя). Тогда конструктор дочернего класса сначала вызывает конструктор родителя, а затем свой уникальный код. При этом порядок вызова не важен!

- parent:: также вызывается при переопределении методов:

public function getSomething() {
$out = parent::methodName();
// операции нового класса
}
PHP - абстрактные классы:

Такой тип классов - своего рода база, на которой строятся остальные, более конкретные классы. Для них заблокирована возможность создавать новые объекты: их задача - наследование.
В PHP абстрактные классы изолируют полем abstract перед словом class.

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

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

В наследуемый абстрактный метод можно добавлять новые аргументы, если делать их необязательными:
function method($arg = something)

Неочевидное преимущество абстрактных классов в том, что пока в дочернем методе не реализованы - или хотя бы не объявлены их абстрактные методы, программа будет выбрасывать ошибку. Хрен забудешь!
PHP - интерфейсы:

Технически, интерфейс - своего рода абстрактный класс, в котором запрещена реализация методов. Все, что можно, это объявлять методы или константы для определения в классах-наследниках.
Унаследованные от интерфейсов константы нельзя перезагружать - то есть, переопеределять. Для других классов это возможно.
Применяют интерфейсы, например, для контроля типов.
Интерфейсы объявляются полем interface и наследуются через implements.
Поподробнее: https://habr.com/post/328890/
Тонкости лексики на примере JS:

- Литерал: значение переменной. Это может быть число, массив, строка, объект - словом, что угодно.
- Идентификатор: название переменной. В коде
const identity = [0,1,2] идентификатор - identity.
- Ключевое слово: то, чем объявляется переменная: const, let, function...
JS - приватность и статика:

- В JS есть два способа работы с методом как со статическим:
1. Обращение к методу класса, а не объекта на его основе;
2. Объявление статического метода ключевым словом static. Это работает, как и в PHP.

- В текущем стандарте JS нет механизма приватности. Она реализуется, например, через замыкания.
JS - полезное:

- Из функций можно вернуть несколько значений. Для этого нужно возвращать либо объект, либо массив.

- Деструктуризирующее присваивание - удобный механизм обработки ключей объектов. Оно активно используется в Node или Реакте. Пример:
const { first, second } = libName;
В этой записи будут созданы две константы со значениями, содержащимися в значениях объекта libName.

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

- Точка с запятой перед IIFE ( ;(function(){}()) ). Зачем её ставят? Это не обязательно, но предотвращает ошибки чтения, если программист не ставит точек с запятой в коде.
JS - this:

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

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

stop: () => {
console.log(Stopped ${this.brand} ${this.model})
}

Здесь контекстом this становится функция, а значит - this ссылается на глобальный объект.

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

- Инстанс: экземпляр класса или объекта. Условный оператор JS instanceof примерно переводится как "экземпляр того" и возвращает true или false в зависимости от того, принадлежит ли объект слева коструктору справа.

- Диспатчинг: перенаправление. Например, в MVC View отлавливает событие и диспатчит в controller.

- Бизнес-логика: уровень абстракции, элемент шаблона проектирования. В MVC бизнес-логика находится на уровне model.

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

Быстрые клавиши в VSCode: File - Preferences - Keyboard Shortcuts
Шорткаты в Гит:
git config --global alias.command-name "command-block"

#шорткаты
Принципы React - повторение:

- Поток данных в Реакте идёт по нисходящей, от родителей к детям. Например, если компонент рендерит 9 более мелких компонентов, данные - пропсы - передаются от этого крупного компонента в мелкий, который и обрабатывает их. Так работает декларативность React.

- В обработчиках компонентов допустимы (и желательны) стрелочные функции.

- State - это "память" компонентов. Например, с помощью state компонент запоминает, что по нему кликнули.

- Без Redux state хранится прямо в компонентах, в кострукторе их классов. У функциональных компонентов state нет: они так и называются - stateless components.

- Как и в PHP, при объявлении конструктора класса-наследника нужно вызвать конструктор родителя. В JS это нужно делать до вызова собственного конструктора наследника.


#react
Принципы Реакт - продолжение:

- Контролируемые компоненты: это компоненты, полностью зависимые от родительских. У них нет своего state и, как правило, своих методов, кроме render. Их состояние хранится в родительских компонентах, а методы передаются через props.

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

- Атрибуты ref могут привести к выстроению императивной системы. Для React это антипаттерн. Об этом позже.

- Функциональные компоненты - способ проектирования Реакт-компонентов, у которых есть только метод render, а остальная информация передается через props. Это более быстрый и чистый способ написания контролируемых компонентов.

#react #функциональные_компоненты
JS - копирование объекта:

- Для копирования объектов есть функция assign. Как она работает:
- функция принадлежит объекту Oblect, поэтому вызывается через Object.assign().
- Она принимает параметры: target - единственный, source - множество, где:
1. target - объект, который возвратит функция.
2. source - объект, из которого копируются ключи-значения.

Пример с клонированием объекта:

let obj = { key: value }
let clone = Object.assign({}, obj)

Здесь функция копирует в пустой объект содержимое obj и присваивает пустой объект переменной clone. Source может быть и объект, определенный прямо в функции.

ВАЖНО: порядок указания sources задает приоритет перезаписи свойств при клонировании. Например в коде:

Object.assign({}, src1, src2)

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

Эта тема важна для понимания иммутабельности в React.

#JS #React
Выгоды иммутабельности в Реакт:

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

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

- Легко выполнять ре-рендеринг компонентов.

- Способствует созданию "чистых" компонентов.

#React #Иммутабельность
JS: spread-оператор для массивов

- Как выглядит spread-оператор:
let clone = [...array];
Внешне он похож на rest-оператор.

- Что он делает?
Раскладывает массив на отдельные элементы.

- Какие задачи решает?
1. Передача массива функции. В ES5 для этого требовался метод apply либо другие, более сложные кастомные функции. Spread упрощает задачу:

const test = (...array) => array.map((i) => i * 2);
console.log(test(...[5, 4, 3])) // 10, 8, 6

2. Клонирование массива (свойств, но не ссылки на оригинал):

const array = [a, b, c];
const clone = [...array]; // [a, b, c]

3. Преобразование коллекций в массивы:

const links = [...document.querySelectorAll('a')];

#JS
JS - деструктуризация объектов:

Рассмотрим сложный случай:

const { hello, bye, space: { full = 'Vacuum' } = {} } = obj;

Что здесь происходит:
1. Объявляется константа.
2. Ей присваевается объект obj;
3. В фигурных скобках создаются константы с именами свойств этого объекта - hello, bye, space, full.
4. Константа space содержит значение по-умолчанию:
1. Если в объекте нет значения space, оно задаётся как новый пустой объект;
2. Если в новом объекте нет значения full (а его там нет), создается константа full со значением по-умолчанию "Vacuum". Если в объект добавить такое свойство, значение по-умолчанию будет проигнорировано.

Боевое применение деструктуризации (и значений по-умолчанию):

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

const handlerFunction = ({login = 'admin', port = '860'} = {}) => { // some code }

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

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

const clone = { ...src1, ...src2 }

#JS
JS - деструктуризация массивов:

Из особенностей деструктуризации массивов можно отметить возможность пропуска элемента:

const arr = ['hello', 'world', 'space', 'name'];
const [,one, ...two] = arr;
// one = world, two = ['space', 'name']

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

#JS