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

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

Начинайте тут: https://yangx.top/code_lab/280
加入频道
!!! На практике конструкторы используются для штамповки однотипных объектов, чтобы не создавать каждый руками.

Их методы нужно выносить за пределы конструктора:
1. так удобнее расширять их. (заметка: узнать про обстановку дел в ЕS6/7);
2. метод, указанный прямо в конструкторе, первый из унаследованных от него объектов не получит.

Конструкторы нужно обязательно вызывать с ключевым словом new. Иначе контекст - this - присвоится в нём глобальному объекту.

Предотвратить ошибку можно так:

function new User(name) {
// code....

if(!(this.instanceof User)) {
return new User(name);
}
this. name = name;
}
}

Ключевое слово instanceof проверяет, каким конструктором создан объект. Слева указывается объект, справа - конструктор. Если значения не совпадают, выбрасывается false и на основе этого можно строить определенную логику.

!!! На практике это нужно, чтобы код работал безотказно у других разработчиков. Именно так работают встроенные конструкторы JS.
В JS массивы - это объекты, или ассоциативные массивы в других языках. В C# массив - непрерывная цепочка байтов в оперативной памяти. Нельзя просто добавить массиву элемент, не создав новый массив.

Конструктор new Array работает специфично:
Любое значение, переданное ему как единственный аргумент, становится указанием, сколько неопределенных - undefined - элементов массива создать. Попавшая в конструктор строка или число типа float вызовет ошибку, целое число - создаст undefined-значения по количеству этого числа.

!!! На практике не нужно использовать конструктор new Array. Литеральная запись функционально повторяет его и превосходит в безопасности. Справедливости ради, я и не использую конструкторы.

!!! То же самое о конструкторе new Number. Если код завязан на проверку типов - то созданное через конструктор число вызовет ошибку.
При вызове метода простой переменной -
string.length()
- интерпретатор временно создаст объект string, методом которой код и воспользуется.

Значениям нельзя присваивать свойства, как объектам. А вот если создать примитив через конструктор - то запросто.

!!! На практике не нужно модифицировать глобальные объекты. Эта проблема специально была решена с помощью примитива symbol в ES6. Из этого следует, что моя библиотека, модифицирующая глобальный объект Date ради пустякового значения, - пример антипаттерна.
Окончательная расстановка точек над функциями, ч.1:

—- Function Declaration - это Объявление Функции. То есть, такая запись:
function foo() {}

—- Function Expresson - это функциональное выражение. То есть, фунция, присвоенная переменной:
const foo = function() {}

—- Named Function Expression - это такое функциональное выражение, где переменной присвоена уже именованная функция:
const foo = function bar() {}.
!!! Практические применения немедленно вызываемых функций - не только изолирование кода от глобальной области видимости. Иногда полезно передать такой фунции глобальный объект под псевдонимом:

(function(global){
global.prototype... // код фнукции
)(this));

Здесь под псевдонимом global в функцию попадает объект window. Это слово - табу для компилятора: оно не ужимается при минимизации и оптимизации. Global же свободно принимает вид "g". Поэтому такой прием хорошо влияет на производительность.
В нативном JS у classList есть метод .toggle() - аналог метода из jQuery. Просто и приятно!
Второй приятный метод classList - .contains(). Проверяет присутствие переданного класса. Удобно вместо value для множественных классов или отхода к ID.Ъ
В функции можно передавать объекты. Даже без реализации паттерна модуль. Объекты - отличный способ доставки, например, атрибутов. Доставленный объект перебирается в функции, и содержимое присваивается, куда надо.
Wordpress

- Тег шаблона - это запись вида <?php the_ID() ?>. Такая запиись вставляется в HTML-код шаблона и модифицирует его по информации из базы, которую вытянет функция.
- Шаблон - это PHP-файл, где закодированы общие элементы страницы, а контент выводится динамически с помошью тегов и циклов.
- Некоторые теги принципиально не работают вне цикла - или, работая, используют только последний пост.
- Под постом в WP можно понимать любой повторяющийся блок контента. Например, карточка товара - в некотором роде пост. (сомнительно, проверить)
Пример разделения вывода HTML в шаблонах по привязке к ID. Warning! Код очень плохой!

https://pastebin.com/jWe31ggm
Wordpress, продолжение:

- Хуки - это встроенные функции WP, к которым можно "прицеплять" свои, кастомные функции.
Пример использования хука:
add_action('publish_post', 'add_point');
Здесь в роли хука-"крючка" выступает функция "publish post". Срабатывая, она тянет за собой функцию "add_point" - и с публикацией поста выполняется её действие.
Полный список хуков есть в Кодексе.
Git

Команда просмотра всех существующих алиасов:
git config --list | grep alias
Wordpress:

Простое правило: если вместо верстки в кишках шаблона php-код - значит, контент надо редактировать в админке.
Функциональное:

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

- Предикаты - это функции, возвращающие 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 нет механизма приватности. Она реализуется, например, через замыкания.