Size: a a a

WiseJS | Frontend tips

2019 April 09
WiseJS | Frontend tips
☑️ КНИГИ ДЛЯ НАЧИНАЮЩИХ И НЕ ТОЛЬКО

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

Книг по программированию, и front-endу ,в том числе очень много. В начале обучения  сложно выбрать актуальный и качественный материал, так как в интернете миллионы ресурсов/видео/самоучителей.

Делюсь книгами, которые помогли мне освоится в технологиях. Интересны они будут новичкам, людям уже что-то знающим, и даже работающим в этой сфере.
P.S.Все книги легко гуглятся в PDF или в  веб формате.

📍Верстка

Начнем с HTML. Не стоит слишком много времени тратить на разбор всевозможных тегов, их вариаций и атрибутов. После стандартного “Hello Wolrd!” и разбора основных тегов можете смело переходить к изучению CSS. Для начала будет полезная  книга
📚 “Новая большая книга CSS” Дэвид Макфарланд (зелено-белая с собачкой на обложке), желательно последнее издание.
Здесь рассматривается HTML в контексте CSS что даст вам сразу же комплексные знания об этих технологиях. В книге хорошие примеры и она просто читается.

Для тех кто чувствует себя уверенно в HTML+CSS рекомендую
📚 “Секреты CSS. Идеальные решения ежедневных задач” Леа Веру. Здесь описываются типичные решения популярных задач, хорошие и плохие подходы. Этих двух книг будет вполне достаточно, чтобы хорошо сверстать почти любой сложности блок.

📍JavaScript

Знакомство с этим языком по моему мнению лучше всего начать с книги
📚 “Выразительный JavaScript” Марейн Хавербек. Здесь рассматриваются основы программирования на JavaScript, а так же предлагаются задания в конце каждого раздела, которые помогут их закрепить.
Параллельно можно обратиться к книге
📚 Дэвида Флэнагана “JavaScript. Подробное руководство”. Эта книга больше похожа на спецификацию и читать ее очень сложно. Но она идеально подходит для разбора и более глубокого понимания тех вещей, которые описаны в предыдущей. После можно пройтись по паттернам:
📚 “68 способов эффективного использования js” Херман Дэвид и
📚 “JavaScript. Шаблоны” Стоян Стефанов. Книги описывают популярные подходы и решения типичных задач.
источник
WiseJS | Frontend tips
☑️ КАК НУЖНО ПИСАТЬ HTML

HTML5
был создан как единый язык разметки, который мог бы сочетать синтаксические нормы HTML(предыдущих версий) и XHTML(более строгий, но устаревший язык разметки). Он расширяет и улучшает разметку документов, а также добавляет единый API для сложных веб-приложений (видео, аудио и т д)

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

Посмотрите на этот кусок кода, является ли он валидным?

<!DOCTYPE html>
<html lang=en>
<head>
   <title>HTML5</title>
<body>
   <p title=question>Is this code valid?

95% разработчиков скажут, что код выше невалидный. Это не так, код полностью валиден (можете убедится сами проверив его на валидаторе https://validator.w3.org/). Но и хорошим таким код не назовешь. HTML5 очень лоялен к разработчику и дает ему слишком много свободы. Многие теги не требуют закрытия, значения атрибутов можно не заключать в "", использовать любой тип регистра.

Код должен быть (касается не только HTML):

✔️ максимально линейным
✔️ читаемым
✔️ управляемым
✔️ коротким
✔️ самодокументируемым

Пишите не только валидный  и понятный браузеру код, а и другим людям.
источник
2019 April 10
WiseJS | Frontend tips
☑️ ПОЛЕЗНЫЕ УНИВЕРСАЛЬНЫЕ АТРИБУТЫ В HTML

Язык HTML – это язык разметки веб-страниц. С помощью тегов вы можете сообщить браузеру, какие элементы будут на этой странице. Но у элементов есть также их свойства и характеристики. Для этой цели в HTML используются так называемые атрибуты. Есть атрибуты которые все знают: id, class, name, type etc.
А есть редкие и не часто используемые, но не менее полезные:

🔻 contenteditable
Когда вы добавляете элементу атрибут contenteditable, браузер делает его доступным для редактирования. Кроме того, все потомки этого элемента также становятся доступны для редактирования. Основное преимущество contenteditable  перед textarea и input в том, что можно вносить любой контент/html и он будет интерактивно отображен в поле ввода (а не просто в виде текста).
💬 Пример:
Facebook и VK для сообщений/записей на стене используют
<div contenteditable=”true”></div>

🔻 hidden
Этот атрибут представляет собой выключатель, который определяет, отображать объект в окне браузера или нет. Им уже “помечены” теги <head> <script> <link>. Аналог в CSS  { display: none; }
💬 Пример:
<div hidden>Скрытый блок</div>

🔻 data-*
В HTML5 для любого элемента можно использовать собственные атрибуты, начинающиеся с префикса data-. Используется для хранения и быстрого доступа к данным в HTML (при взяимодействии с JavaScript), а также для оформления элементов через CSS (очень редко).
💬 Пример:
<div data-user-id=”73612873”>Валидный блок с данными в атрибуте</div>

🔻 aria-*, role
Эти атрибуты оказывают влияние лишь на то, как страница представляется программами экранного доступа через речевой или тактильный вывод информации. Позволяют сделать вашу страницу более доступной, в некоторых случаях служат дополнением или заменой семантическим тегам.
💬 Пример:
<aside role="complementary" aria-label="Реклама">
  Рекламный блок
</aside>


🔻 download (на элементах управления)
При наличии данного атрибута браузер не переходит по ссылке, а предложит скачать документ, указанный в адресе ссылки. В качестве значения можно указать рекомендуемое имя файла для сохранения на диск пользователя.
💬 Пример:
<a href="image/xxx.jpg" download>Скачать файл</a>

И последний - микроразметка
Относится больше к продвижению сайтов, а не разработке.

🔻 itemscope, itemtype, itemprop
Микроразметка — своего рода единый язык, который одинаково понимают и трактуют поисковые роботы Google, Яндекс, Bing, Yahoo и т д.

itemscope — описывает каждый блок отдельно, позволяет описать информацию на уровне сущности;
itemtype — указывает тип сущности;
itemprop — позволяет указать дополнительные свойства. Например, сущность — театральное событие. В таком случае можно указать название, дату спектакля, место проведения.

💬 Пример:
<div itemscope="" itemtype="TheaterEvent">
<span itemprop="name">Viva Штраус</span>
<div itemprop="location" itemscope="" itemtype="PerformingArtsTheater">
<meta itemprop="name" content=“
site”/>
<link itemprop="sameAs" href=“sitehref”/>
<meta itemprop="address" content=“
Киев, Украина"/>
</div>
   <span itemprop="startDate" content="2016-25-12T19:00">Sun 25 December 2016 19:00</span>
</div>
источник
2019 April 11
WiseJS | Frontend tips
☑️ РАЗЛИЧИЕ МЕЖДУ АБСОЛЮТНЫМИ И ОТНОСИТЕЛЬНЫМИ ПУТЯМИ. В ФАЙЛОВОЙ СИСТЕМЕ И НА САЙТЕ.

Сайт существует как бы в двух измерениях. Реальном (локальном) и виртуальном (удаленном).

Для посетителей - это виртуальный веб-сервер. Который отличается, в числе прочего, тем, что на нем не существует файлов (за некоторыми исключениями). Если вы пишете http://site.com/file.html - это не файл. Это URI, виртуальный адрес. Файла с именем file.html на сервере может вообще не быть. Это все виртуальные адреса, а не файлы. И браузер работает именно с адресами.

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

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

Для успешного и правильного использования путей нужно понимать 2️⃣ вещи:
📍 Различать корень веб-сервера, как его видит браузер, и корень файловой системы на диске.
📍 Отличать относительные путей от абсолютных

Сегодня мы разберем второй пункт:

🔻 Абсолютный путь — это путь от корневой папки к файлу. Другими словами - когда ссылка представляет из себя полный URL файла или страницы.

💬 При работе с внешними файлами используются такие обсолютные пути
<link href="https://site.com/css/style.css" rel="stylesheet">
<link href="//site.com/css/style.css" rel="stylesheet">

В данном случае всё очень просто, мы указываем прямой путь к файлу, лежащему на другом домене. Возможно указание сокращенного пути через использование двух слешей в начале без явного указания http или https и сервер сам подставит нужный протокол.

💬 При работе с файлами на собственном веб сервере стоит использовать такую запись
<img srс=”/img/frame.gif”>
В юникс-системах и на веб сайтах корень обозначается косой чертой - "/".
Это важно. Это не просто палочка, а самостоятельный адрес, путь.

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

🔻 Относительный путь к файлу от документа — это путь к файлу относительно текущего документа. Такой адрес зависит от расположения файла, в котором он записан.

💬  Самый простой пример относительного пути - это просто имя файла
<a href=”file.html”>
<img src=”../blog/main.html”>

💬 Некоторые системы требуют такой записи
<a href=“./file.html”>
<img src=“./../blog/main.html”>


❕И операционная система, и браузер, встретив относительный путь, достраивают его до абсолютного. но каждый - по-своему. Для предопределения приставки к относительному пути можно использовать тег <base>. Он предназначен для документов, в которых используется относительный адрес и эти документы могут переноситься в другую папку или даже на другой компьютер без потери связи. Браузер ищет тег <base>, определяет полный адрес документа. Например, если адрес документа указан как <base href="http://site.com/hzchd/">, то при добавлении рисунков достаточно использовать относительный адрес <img src="images/cat.gif">. При этом полный путь к изображению будет http://site.com/hzchd/images/cat.gif, что позволяет браузеру всегда находить графический файл, независимо от того, где находится текущая веб-страница.

Попробуйте потренироваться в использовании относительных путей как на локальном компьютере, так и на веб-сервере. Понимание того, как это работает, непременно пригодится вам в любом проекте.
источник
2019 April 17
WiseJS | Frontend tips
☑️ МАЛОИЗВЕСТНЫЕ CSS СЕЛЕКТОРЫ

Селекторы (от select) - это элементы каскадной таблицы стилей CSS, которые указывают на тот элемент на веб-странице, к которому должны будут применяться стили. Здесь будут выделены те селекторы, которые встречаются не часто, но могут быть полезны в некоторых ситуациях. В том числе присутствуют некоторые селекторы level 4, они здесь будут отдельно выделены(🔜). У них не очень хорошая поддержка браузерами, так как эта часть документации еще в драфтовом режиме, но в ближайшее время может быть утверждена. Перед их использованием убедитесь в поддержке вашим браузером!

⚡️:only-child
Этот применяется к дочернему элементу, только если он является единственным у родителя. Пригодится когда нужно прописать больший/меньший отступ/границу для тех элементов, которые содержат только один дочерний элемент, или же вы можете уменьшить размер шрифта если элемент содержит несколько дочерних элементов.

⚡️:target
Этот псевдо-класс позволяет связать гиперссылку <a> с любым элементом на странице, при этом значение атрибута href ссылки должно начинаться с символа # и содержать идентификатор id выбранного элемента (якорь). При нажатии на ссылку с идентификатором якоря, псевдо-класс :target применяет заданный стиль к элементу с якорем. То есть, когда мы кликаем по ссылке, в адресе которой содержится фрагмент идентификатора элемента, этот элемент становится целью (отсюда и :target).

⚡️:empty
Псевдокласс представляет пустые элементы, которые не содержат дочерних элементов, текста или пробелов. К примеру, <p></p> является пустым элементом, а <p> </p>, <p>&nbsp;</p> или <p>тест</p> уже нет.

⚡️:root
Находит корневой элемент дерева документа. Применимо к HTML, :root находит элемент <html> и идентичен селектору по тегу html, но его специфичность выше.

⚡️:not(X)
Отрицательный CSS псевдо-класс,  - функция, принимающая простой селектор X в качестве аргумента. Он находит элементы, не соответствующие селектору. X не должен содержать других отрицательных селекторов.

⚡️ :any 🔜
Селектор создан для того чтобы объединить несколько селекторов вместе, чтобы получить тот же самый эффект. Таким образом повышая читабельность вашего CSS-файла.

:any(section, article, aside)
:any(li, nav, header, footer) a {
color: #000;
}


⚡️:has 🔜
Данный селектор позволяет указать, какие объекты должны присутствовать внутри указанного элемента, для того, чтобы это правило сработало по отношению к нему. Для примера, мы можем выбрать все секции, в которых присутствуют заголовки:
section:has(h1, h2, h3, h4, h5, h6)

⚡️:any-link 🔜
Оно объявлено для соответствия любому из свойств :link или :visited.
a:any-link { ... } - то же самое что и
a:link, a:visited { ... }

⚡️:local-link 🔜
Этот элемент выбирает элементы, которые ссылаются на эту же страницу. Если ссылка включает в себя фрагмент настоящей ссылки, то она тоже подпадает под селектор. Если же нет, то фрагмент части ссылки настоящего URL не рассматривается.

⚡️:dir(ltr | rtl) 🔜
Cопоставляет элементы в зависимости от направления содержащегося в них текста. Может быть полезен при работе над приложением с поддержкой восточных языков (Арабский, Турецкий и т д)
ltr - текст слева направо
rtl - текст справа налево
источник
WiseJS | Frontend tips
Что вам наиболее интересно?
Окончательные результаты
38%
технологии HTML/CSS/JS, интересные моменты, неочевидные вещи, полезные советы
8%
материаллы (ссылки на полезные ресурсы, книги, видео и т д)
30%
первая работа и собеседования (вопросы, задачи, тестовые задания, как готовиться)
24%
код ревью (примеры хорошего/плохого кода с объяснениями)
Проголосовало: 37
источник
2019 April 18
WiseJS | Frontend tips
☑️ CSS СВОЙСТВО currentColor

💬 Посмотрите на этот CSS код:
.test {
 color: red;
 border: 5px solid;
 box-shadow: 0 0 5px 5px;
 height: 50px;
}


Кажется что чего-то не хватает. Мы опустили значения border-color и не указали цвет тени, значит ли это, что наш код не будет работать?
На самом деле - нет. Этот код полностью рабочий и правильный - и дело здесь в такой штуке как currentColor.

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

💬 В примере выше можно явно указать это свойство:
.test {
 color: red;
 border: 5px solid currentColor;
 box-shadow: 0 0 5px 5px currentColor;
 height: 50px;
}


Другими словами: ключевое слово currentColor позволяет в свойствах элементов наследовать значение свойства color.
Есть свойства и элементы, которые наследуют значение color по умолчанию:
📍Цвет границы
📍Цвет границы элемента <hr>
📍Значение свойства box-shadow
📍Цвет текста элемента
📍Значение свойства outline
📍Цвет маркеров и границы элементов списка
📍Цвет атрибута alt элемента img.

Есть ряд случаев, когда может пригодиться получение значения свойства color. Один из примеров, когда значение свойства color не наследуется по умолчанию — это градиенты. Линейный и радиальный градиенты CSS не наследуют свойство color.

💬 С помощью currentColor вы можете создать градиент, использующий основной цвет темы:
background-image: linear-gradient(to bottom, currentColor, #fff);

💬 Также свойство currentColor можно очень эффективно использовать на псевдо-элементах ::before & ::after
a:hover::after,
a:focus::after,
a:active::after
{
   border-left-color: currentColor;
}


Вооружившись этим свойством мы очень просто можем изменять  тему определенных блоков или даже всей страницы.
💬 Код из картинки в приложении с использованием данного свойства может выглядеть так (ссылка на скриншот https://i.ibb.co/DPXX1Bg/Screen-Shot-2019-04-18-at-12-26-33-PM.png):
svg {
   fill: currentColor;
}

.button {
   color: #000;
   border: 2px solid currentColor;
}
.button:hover,
.button:focus {
   color: #333;
}
.button:active {
   color: #666;
}
источник
2019 May 02
WiseJS | Frontend tips
☑️ ПРАВИЛА СРАВНЕНИЯ В JAVASCRIPT

В JavaScript существует несколько основных типов данных. А также множество операторов для работы с ними. Eсть два набора операторов равенства строгие : === и !==, и нестрогие == и !=. Строгие работают так, как вы ожидаете. Если два операнда имеют один и тот же тип и имеют одинаковое значение, то === выдает true а !== выдает false. Нестрогие поступают правильно, когда операнды относятся к одному и тому же типу, но если они относятся к разным типам, они пытаются привести значения. Ни одно собеседование не обходится без вопросов про приведение типов и их сравнение, а также, понимание этих правил поможет вам избежать ошибок и многих часов отладки вашего кода.

🔻СРАВНЕНИЕ ПРИМИТИВОВ (по обе стороны от оператора типы: number, string, boolean, null, undefined)

Оператор тождества или идентичности (далее ===) вычисляет значения своих операндов, а затем сравнивает, без преобразования типов по таким правилам:
⚡️Если у значений разные типы — они не идентичны.
2 === "2" // false
⚡️Если оба значения или null или undefined — они идентичны.
null === null // true
undefined === undefined //true
⚡️Если оба значения или true или false — они идентичны.
true === true // true
⚡️Если одно или оба значения — NaN — они не идентичны.
NaN === NaN // false
⚡️Если оба операнда это числа с одним и тем же значением — они идентичны. Если одно число равно 0, а другое -0, они также идентичны.
2 === 2 //true
⚡️Две строки строго равны только в том случае, если они имеют одинаковую длину, и те же символы в одинаковой последовательности и соответствующих позициях.
"hello" === "hello" // true

Оператор равенства (далее ==) похож на оператор идентичности, но он использует менее строгие правила. Если у значений разные типы — они преобразуются и сравниваются:

⚡️Если у значений одинаковый тип, они проверяются на идентичность, без преобразований (по правилам описанным выше).
⚡️Если одно значение null, а другое undefined — они равны.
null == undefined // true
⚡️Если одно значение число, а другое строка, то строка преобразуется в число и выполняется сравнение.
"2" == 2 // true
⚡️Если одно значение — true, оно перед сравнением преобразуется в 1. Если — false, оно преобразуется в 0 и сравнение выполняется снова.
true == 1 // true

🔻СРАВНЕНИЕ ССЫЛОЧНЫХ ТИПОВ (по обе стороны от оператора типы: объекты, массивы, функции)

Здесь все работает одинаково для == и === :

⚡️Если оба значения ссылаются на один и тот же объект, массив или функцию — они идентичны.
const a = {};
b = a;
a === b // true

⚡️Если оба значения ссылаются на различные объекты — они не идентичны, даже при идентичных свойствах.
{} === {} // false
[] === [] // false


🔻СРАВНЕНИЕ ССЫЛОЧНЫХ ТИПОВ ДАННЫХ С ПРИМИТИВАМИ (с одной стороны примитивы,  с другой ссылочные типы)
При строгом сравнении (===) всегда false
При нестрогом сравнении (==):
⚡️Если одно значение число или строка, а другое — объект(функция, массив), то перед сравнением объект преобразуется в простой тип. Встроенные классы преобразуются методом valueOf(), если не получилось, то toString() для чисел и обратный порядок для строк (сначала то toString() потом valueOf()). Класс Date всегда выполняет преобразование toString().

Иногда примитивы и ссылочные типы данных могут быть очень похожи. С точки зрения программиста примитивное значение типа string и объект, созданный из строки конструктором String(), практически неотличимы, и даже во многих книгах этот момент упоминается мимоходом, без конкретных примеров.

const a = "строка";
const b = new String(a);
const c = new String(a);

a==b // true (преобразование типов)
a==c // true (преобразование типов)
b==c // false (2 разных обьекта)


На практике рекомендую отказаться от использования == в сторону ===. Используя строгое сравнение можно быть уверенным в возвращаемом значении.  В примере ниже можете проверить себя в приведении типов при сравнении (https://ibb.co/K9PNct1). Будьте внимательны при сравнении переменных!
источник
2019 June 14
WiseJS | Frontend tips
☑️ НОВЫЙ АТРИБУТ inputmode ДЛЯ МОБИЛЬНЫХ ОС И БРАУЗЕРОВ

Формы являются главным типов взаимодействия на сайтах и в приложениях. Форма -  это просто путь к результату. Заполнение формы должно быть быстрым и понятным. Но заполнять формы с мобильных устройств это та еще задача. Упростить её для пользователей можно используя атрибут inputmode на элементах формы (input).

💬 Пример: <input type="text" inputmode="" />

inputmode не меняет способа, которым браузер интерпретирует input (этим занимается атрибут type) – он даёт браузеру инструкцию, какую виртуальную клавиатуру вывести на экран.

Поддерживаемые значения атрибута:

🔻 email -  добавляет символ @ и десятичную точку на стандартную клавиатуру. Пользователю не нужно переключать раскладку для ввода этих символов.

🔻 tel - клавиатура похожа на numeric, является копией клавиатуры кнопочных телефонов. Поддерживает цифры от 0 до 9, символы решётки, звёздочки и другие (все что может понадобится при наборе номера телефона).

🔻 search - виртуальная клавиатура, оптимизированная для поиска. Например, ключ возврата может быть переименован в «Поиск», и могут быть другие оптимизации.

🔻 numeric - циферная клавиатура, идеально подходит для полей ввода, которые требуют только чисел – например, пин-коды, почтовые индексы, номера кредитных карт, и т.д.

🔻 url - позволяет добавить расширение имени домена (например, .com) путём нажатия одной кнопки. Также на основной клавиатуре появляются кнопки, которые обычно используются для веб-адресов, например, символы (.), (www.), (/).

🔻 none -  в документации сказано что никакой клавиатуры не будет, использовать когда сайт реализует собственную клавиатуру. В IOS появляется стандартная клавиатура.

🔻 text - cтандартная клавиатура для ввода текста.

Поддержка браузеров пока не лучшая ( https://caniuse.com/#feat=input-inputmode ), но вреда от данного атрибута чотно не будет, а при срабатывании сделает вашего пользователя немного счастливее. 🎆

P.S: Как вы могли заметить на канале был небольшой перерыв, отныне я буду публиковать по 3 поста в неделю. Stay tuned! 📡
источник
2019 June 18
WiseJS | Frontend tips
☑️ ВОПРОСЫ НА СОБЕСЕДОВАНИИ #1

За время работы я побывал на многих собеседованиях, еще больше провел и регулярно продолжаю это делать (по 2-3 в неделю), так как мы активно ищем разработчиков уровня junior+ и middle. В постах такого типа будем разбирать задания, с которыми у людей возникает наибольшее количество трудностей. Первый цикл будет посвящен разбору кусков кода и вопросов по нему. Поехали:

🔻 Задание 1:  Что мы увидим в консоли и почему?
function greeting() {
 console.log(name); // ?
 console.log(age); // ?

 var name = “Alex”;
 let age = 25;
}

greeting();


Ответ:
console.log(name); // undefined
console.log(age); // ReferenceError

💬 Пояснение:
var обладает функцирнальной областью видимости.
Переменные обьявленные с ключевым словом var  поднимаются (всплывают) внутри функции (области видимости), где они определены, перед тем, как код будет выполнен.
Код:
console.log(name);
var name = “Alex”;

идентичен следующему:
var name;
console.log(name);
name = “Alex”;



let и const обладают блочной областью видимости.
Они не “всплывают” и живут исключительно в рамках своего блока “{…}”. Не важно будь это функция, цикл или просто блок скобочек. Они недоступны до того, как мы объявим (инициализируем) их. При обращении к переменной age мы получим ошибку ReferenceError.

🔻 Задание 2: Что выведет данный код?
const a = 3;
const b = new Number(3);
const c = 3;

console.log(a == b); // ?
console.log(a === b); // ?
console.log(b === c); // ?


Ответ:
console.log(a == b); // true
console.log(a === b); // false
console.log(b === c); // false


💬 Пояснение:
Хотя new Number() и выглядит как число, на самом деле его тип “object”. Оператор == приводит переменную b к числу. a и b имеют значение 3, поэтому оператор возвращает true. Однако, когда мы используем оператор ===, значение и тип должны быть одинаковыми. Это не так: new Number() - это не число, это объект. Оба возвращают false.
Более детально про приведение типов - пост выше в этом же канале (ПРАВИЛА СРАВНЕНИЯ В JAVASCRIPT)

🔻Задание 3: Какой будет результат вывода?
const a = {};
const b = { prop: "b" };
const c = { prop: "c" };

a[b] = 123;
a[c] = 456;

console.log(a[b]); // ?


Ответ:
console.log(a[b]); // 456

💬 Пояснение:
Ключи объекта автоматически преобразуются в строки (так как ключи - только примитивы). Мы пытаемся установить объект как ключ к объекту со значением 123. При преобразовании объекта в строку, он становится “[Object object]”.
Код:
a[b] = 123;
идентичен следующему:
a[“[Object object]”] = 123;

Затем мы пытаемся сделать то же самое с другим обьектом.  Он так же преобразуется в “[Object object]”.
Код:
a[c] = 456;
идентичен следующему:
a[“[Object object]”] = 456;

Затем мы записываем a[b], используя один и тот же ключ. Потому перезатираем предыдущее значение.
И при обращении код:
console.log(a[b]);
идентичен следующему:
console.log(a[“[Object object]”]); // 456
источник
2019 June 24
WiseJS | Frontend tips
☑️ СВОЙСТВА object-fit И object-position

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

📍 object-fit
Определяет, каким образом содержимое замещаемых элементов будет подогнано к краям контейнера тега в случае, когда для элемента заданы ширина и высота, отличные от его собственных размеров.

Значения:

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

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

🔻cover
содержимое элемента обрезается, выравниваясь по центру с сохранением пропорций таким образом, чтобы полностью заполнить область контейнера

🔻scale-down
содержимое элемента выбирает из двух значений none и contain то значение, которое даёт меньшие размеры

🔻none
замещаемое содержимое не изменяет свои собственные размеры, чтобы поместиться и заполнить область контейнера

Пример использованя взят с htmlbook
( https://www.dropbox.com/s/wi7zsqq8akewgyt/object-fit.jpg?dl=0 )

📍object-position
Используется в сочетании с object-fit и задаёт положение содержимого замещаемого элемента внутри контейнера относительно координатных осей X и Y. Значение по умолчанию 50% 50%. Свойство анимируется. Позиционирование по горизонтали и вертикали задаётся с помощью пары ключевых слов (как с background-position) или любые единицы измерения css.

Минус этих свойств всего один - они не работают в IE. Как альтернативу без JS там можно использовать background-image и аналогичное свойство background-size.
источник
2019 July 01
WiseJS | Frontend tips
☑️ CSS Shapes

Обратите внимание на картинку внизу поста (https://www.dropbox.com/s/fchqrmrmj4oe486/css-shape.png). Не так просто добится такого результата на веб-сайте для любого количества текста.

Сегодня мы можем задавать объекту любую форму CSS-трансформациями (transform), но эти формы не могут влиять на поведение содержимого внутри них или вокруг них. Например, если вы создаете треугольник или трапецию с помощью CSS, то созданная форма не влияет на то, как будет вести себя текст внутри фигуры или вокруг.

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

Мы можем определить в CSS все виды базовых фигур, применив к свойствам shape-inside или shape-outside следующие значения функций:

🔻 circle(cx, cy, r);
Описывает круг, значения cx и cy определяют координаты центра круга, r — радиус.

🔻 ellipse(cx, cy, rx, ry);
Описывает окружность, значения cx и cy определяют координаты центра окружности, rx и ry — радиус.

🔻 rectangle(x, y, width, height, [rx, ry]);
Описывает прямоугольник, значения x и y определяют позицию формы, width и height — ширину и высоту, rx и ry — радиус углов.

🔻 polygon(x1 y1, x2 y2, ..., xn yn);
Описывает многоугольник на основе переданных координат.

🔻 url(path/to/the/image.svg);
Описывает форму заданную выбранным изображением или SVG файлом.

Примеры использования можно посмотреть в документации ( https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Shapes/Overview_of_CSS_Shapes ).

Чтобы применить свойство shape-outside к элементу, этот элемент должен быть плавающим (float: left|right) и иметь определенные высоту и ширину. В будущем возможности CSS-форм позволят использовать формы не только для плавающих элементов, и когда это случится, контент сможет обтекать форму с двух сторон.

Поддержка браузерами у CSS Shapes хорошая, работает во всех современных браузерах (IE11 не работает, но и современным его не назовешь). Если вы хотите использовать CSS Shapes в браузерах, которые не поддерживают данную технологию eсть плагин, который доступен на Github (https://github.com/adobe-webplatform/css-shapes-polyfill).
источник
2019 July 04
WiseJS | Frontend tips
☑️ ПОЛЕЗНЫЕ CSS ФУНКЦИИ

Разница между CSS функцией и просто значением свойства в том, что функция вызывается символом (), и может принимать аргументы. Если вы не сталкивались с функциями ранее, то на примерах ниже быстро разберётесь. Поехали:

🔻 attr()
Это функция, которая возвращает значение переданного атрибута элемента в виде строки.

💭Например attr(href) в следующем коде:

.selector {
   a[href]::after {
     content: attr(href);
   }
}


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

<a href=“#some-path”></a>

#some-path не нужно вставлять в контент

Соответственно можно взять абсолютно любой атрибут и использовать его таки образом. В том числе и пользовательские data-* атрибуты. Что дает возможность изменять их значение через JavaScript.

🔻 calc()
Данная функция  принимает в качестве параметра математическое выражение, результат вычисления которого можно использовать как значение CSS свойства. Выражение может включать операторы +, -, *, /.
Операнды в выражении могут быть в различных единицах измерения width: calc(100% - 80px)
❗️Операторы (+ , - и другие) всегда должны быть по обеим сторонам отеделены пробелом.

💭 Пример:
Возможно вы желаете отступ, связанный с размером шрифта, вроде 4em? Не проблема.

.element1,
.element2 {
 width: calc(50% - 2em);
}

Или сделать один столбик резиновым, а другой статическим

.static {
 width: 200px;
}
.responsive {
 width: calc(100% - 200px);
}

Выравнивание элемента по центру (вертикально)

.element {
 margin-top: calc( 50% - 25px );
}


Половина высоты родителя минус половина высоты дочернего элемента.

🔻 counter()
CSS счетчики, в своей сущности, переменные CSS, значения которых могут быть инкрементированы для отслеживания количества их использования. Они позволяют регулировать внешний вид контента, основываясь на его местоположении в документе.

💭 Пример:
body {
 counter-reset: section;  /* Устанавливает значение счетчика, равным 0 */
}

h3::before {
 counter-increment: section;  /* Инкрементирует счетчик */
 content: "Секция "counter(section) ": "; /* Отображает текущее значение счетчика */
}


Используем три свойства CSS: counter-reset, counter-increment, content и функция counter(). Если какое-либо из указанных свойств будет пропущено, то метод не будет работать.

💭 Пример:
и следующий код на странице
<h3>Вступление</h3>
<h3>Основная часть</h3>
<h3>Заключение</h3
>

будет выглядеть как:

Секция 1: Вступление
Секция 2: Основная часть
Секция 3: Заключение

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

Все вышеперечисленные свойства хорошо поддерживаются современными браузерами начиная с IE9.
источник
2019 July 05
WiseJS | Frontend tips
Информация для тех кто пришёл с вебинара:
Пост с книгами по изучению веб технологий закреплён!
Удачи в обучении 💫
источник
2019 July 09
WiseJS | Frontend tips
☑️ НУЖНО ЛИ КОММЕНТИРОВАТЬ КОД

Начиная изучать программирование, в том числе языке разметки вы знакомитесь с такой штукой как комментарии. Комментарий — это строка в исходном коде, которую могут прочесть разработчики, но которая игнорируется компиляторами и интерпретаторами (т. е. не исполняемый код).
Посмотрите на следующий пример: (примеры кода взяты с medium/nuances-of-programming):

let o_fac = new BGF()
let bg_a = o_fac.build("ALIEN");
bg_a.i_health(100);
bg_a.i_armor(50);
bg_a.i_attack(50);
game.v_Add(bg_a);


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

// create the alien object.
let o_fac = new BGF()
let bg_a = o_fac.build("ALIEN");

// set Alien details.
bg_a.i_health(100);
bg_a.i_armor(50);
bg_a.i_attack(50);

//add to game
game.v_Add(bg_a);


Разве читабельность кода не возросла? Все потому, что комментарии описывают то, что делает код, в то время, как сам код показывает, как это делается. Получается, что комментарии объясняют наш код, но пояснять код можно разными способами. И комментирование является самым худшим из них.

И причин для этого несколько:

🔻 Мало кто из разработчиков обращает на внимание на комментарии.

🔻 Нельзя верить комментариям, которые вы читаете. Источником истины является код. Комментарии часто не обновляют после изменения коди и они попросту не соответствуют дейтсвительности.

🔻Комментарии которые я встречал делали не очень позеные вещи:
- извенение за сложность или длину кода
- хак/костыль
- извенение за неправильное именование переменных или функций
- бесполезные комментарии типа
i++; // Увеличиваем счетчик

А что насчет предыдущего кода? В нем комментарии казались полезными. На самом деле комментарии маскировали проблему, а не решали её. Мы можем создать обертку над уже готовым функционалом:

const alien = alienFactory
             .createAlien()
             .withStats({
                 health: 100,
                 armor: 50,
                 attack: 50
               })
             .getAlien();

game.add(alien);


Еще один плюс от использования фабрик-оберток в том, что все лишние детали скрыты. Нам не придется думать о том, как работают функции, не относящиеся к отдельно взятому изменению в коде. И так код становится удобнее для понимания.

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

И в заключение - как выглядит 90% комментариев (https://www.dropbox.com/s/b23v6x56btrrlt5/cat-code.jpg):
источник
2019 July 18
WiseJS | Frontend tips
☑️ CSS СВОЙСТВА КОТОРЫЕ ВЫ НЕ ИСПОЛЬЗУЕТЕ

При разработке интерфейса мы пользуемся определенным набором css свойств. Например блоки верстаем через flexbox, для обтекания используем float, для фона background. Сегодня мы посмотрим на свойства которые помогут разнообразить верстку и упростить некоторые моменты. Возможно в будущем будет обзор каждого свойства - если будет актуально.

🔻 Раскладка:
Cейчас большинство разработчиков использует flexbox для разметки основных частей сайта. часто забывая о технологии grid. Его можно и нужно использовать для глобальной раскладки сайта, для сложных сеток и компонент.
Так же есть технология под названием CSS Multi columns. С отличной поддержкой браузерами (в том числе IE 10). Универсальное свойства columns: [column-width] || [column-count], позволяют одновременно задать ширину и количество колонок многоколоночного текста.

🔻 Анимации и трансформации:
Все знают и используют для анимации transform + transition. Но мало кто использует свойство will-change. CSS Will Change позволяет подготовить браузер перед изменением состояния элемента. Браузер сможет подготовиться к этой оптимизации, например, перерисовке.

💭 Пример:
div {
   will-change: transfrom;
}


🔻 Переменные в CSS:
Это сущности,, хранящие конкретные значения, которые можно повторно использовать в документе. Они устанавливаются с использованием custom property нотации (например. --main-color: black;) и доступны через функцию var() (например. color: var(--main-color);)

💭 Использование:
.element {
 --main-bg-color: brown;
}

.element {
 background-color: var(--main-bg-color);
}


🔻 Интерактивность:
Интересная технология Scroll snap контролирует поведение скролла. Например, есть горизонтальная прокрутка. Когда мы прокручиваем контент, он останавливается в том месте, до которого прокрутили. С помощью Scroll snap страница будет автоматически докручиваться до границы элемента, на котором остановилась, какой бы высоты он ни был. Так же работает горизонтальное выравнивание по центру/верху. Это отличный пример, что можно не использовать JavaScript для простых задач.

💭 Пример использования:
.container {
   scroll-snap-type: x mandatory;
   scroll-padding: 50%;
}
.child {
   scroll-snap-align: center;
}


🔻 Направление текста
Существует 4 системы написания. Они характеризуются направлением написания и чтения символов по вертикали и горизонтали.
Latin based — стандартная система: читаем слева направо и сверху вниз.
Arabic based — справа налево и сверху вниз.
Han based — азиатская группа, может быть по-разному (слева направо или наоборот).
Mongolian based - тот же latin based с поворотом всего на 90%.

Каждый день такие задачи не ставят, но столкнувшись с ними вы пойдете использовать transform: rotate. Не то, чтобы transform — это неверно, но с CSS Writing Modes — правильнее.

💭 Использование:
.element {
writing-mode: horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr;
}


Свойство определяет направление потока блока, в каком направлении складываются контейнеры уровня блока и направление в котором инлайновый контент находится в родительском блоке.
источник
2019 July 21
WiseJS | Frontend tips
☑️ КАК УСКОРИТЬ ЗАГРУЗКУ GOOGLE FONTS В 4 РАЗА

В разработке очень часто приходится использовать шрифты с Google Fonts (большая библиотека свободно распространяемых шрифтов). Ибо стандартные шрифты никого не устраивают, а хранить шрифты у себя не всегда хочется. Да и сервис очень популярный и вероятность что у пользователя уже есть нужные сайту шрифты очень высока. Сам сервис предлагает вам несколько способов подключения шрифтов:

1. с помощью тега <link> в <head> документа
2. @import в css файле

На примере разберем почему оба этих способа являются медленными:

Допустим нам нужно загрузить 2 шрифта Lato и Racing-Sans-One (способ работает со всеми шрифтами). Ссылка на подключение будет выглядеть таким образом

<link href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i|Racing+Sans+One&display=swap" rel="stylesheet">

Здесь мы грузим не шрифты, а таблицу стилей (css файл). И уже внутри этого файла @font-face загружает ресурсы шрифтов. То есть мы делаем 3 запроса:
Таблица стилей, и по запросу за каждым шрифтом.

Во втором пункте все еще хуже, мы делаем запрос за нашей таблицей стилей, а после всё те же 3 запроса. В итоге получаем 4. При хорошем интернет соединении на MacbookPro в последней версии Google Chrome затраченное время  ~200-250 ms (ms - миллисекунд) в первом случае и ~230-280 ms во втором.

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

❌  FOIT (вспышка невидимого текста) - шрифтов вовсе нет - и через 200-250 ms они появляются.

❌  FOUT (вспышка неустановленного текста) - отображается fallback шрифта (стандартный браузерный) и после загрузки он изменяется на шрифт из Google Fonts.

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

🚀 Начинаем ускорять:

Мы знаем что наш сервис ипользует домен fonts.gstatic.com для загрузки шрифтов,  потому мы можем использовать preconnect.

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>

preconnect позволяет браузеру установить соединение прежде, чем HTTP-запрос будет отправлен на сервер. Эта процедура включает поиски DNS, «переговоры» TLS и «рукопожатие» TCP. Что в свою очередь устраняет круговые задержки и экономит время пользователя. (не работает в IE). Для IE можно использовать rel=“dns-prefetch”. Тоже сэкономит немножко времени.

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

Для этого пойже пройти в файл с таблицей стилей который мы грузили (в нашем случае это https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i|Racing+Sans+One&display=swap) и берем прямые сслыки на шрифты.
Смотрим на атрибут src: url().
Например для Lato - это url(https://fonts.gstatic.com/s/lato/v15/S6uyw4BMUTPHjx4wXiWtFCc.woff2)

Подключаем его с помощью тега <link> с особым набором атрибутов:

<link rel="preload" as="font" type="font/woff2" href=“тут ссылка на шрифт” crossorigin>

что делают эти атрибуты:
🔻 href - ссылка на ресурс (CDN шрифа)

🔻 rel=“preload” указывает браузеру декларативно извлекать ресурс, но не «исполнять» его (наш CSS будет поставлен в очередь использования).

🔻 as=“font” указывает браузеру, что он должен загружать, чтобы он мог установить соответствующий приоритет. Без этого браузер установил бы низкий приоритет по умолчанию.

🔻 type=“font/woff2” указывает браузеру тип файла, чтобы он загружал ресурс, только если он поддерживает этот тип файла.

🔻 crossorigin необходимо, потому что шрифты выбираются с использованием анонимного режима CORS.
источник
WiseJS | Frontend tips
Дальше подключаем загруженные шрифты в теге <style> если у вас SPA (сэкономите еще пару десятков секунд) или в вашей таблице стилей.

@font-face {
   font-family: 'Lato';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: local('Lato Regular'), local('Lato-Regular'), url(“сслыка на шрифт”) format('woff2');
   unicode-range: /* какой диапазон символов будет загружен из шрифта */
}


Если в правиле была объявлена функция local(), с названием шрифта, то будет производиться поиск на компьютере пользователя, и в случае обнаружения будет использован этот шрифт. Иначе будет скачан и использован шрифт, указанный в функции url().

Полное время загрузки сократилось до 40 - 50 ms. Код примера можно посмотрель здесь: https://codepen.io/anon/pen/MNwxzg
источник
2019 July 23
WiseJS | Frontend tips
☑️ ЭФФЕКТИВНЫЙ КОД #1 HTML

Каждый день я читаю много кода. Просматривая домашки студентов, pull requestы на работе, тестовые задания кандидатов, или просто код людей которые его шарят в linkedin, twitter и github. Расскажу про некоторые вещи, которых лучше избегать при верстке сайта, ведь даже валидный и кроссбраузерный сайт может быть сверстан отвратительно. В свою очередь написание хорошего кода делает простым поддержку, доработку и масштабирование сайта. Некоторые моменты покажутся очевидными для опытных разработчиков, но начинающим будет полезно. Далее по пунктам:

🔻 Не используйте теги с целью стилизовать контент, а также “Deprecated tags” (устаревшие теги)
Теги <font>, <u>, <mark>, <s>, <big>, <center>, <strike>, <blink> (и прочие стилистических элементы)
Это задача CSS, не стоит мешать разметку со стилями в HTML

🔻 Не используйте устаревшие атрибуты и атрибуты для стилизации
start у <ol>, width у <hr> <img> и других, align у текстовых, и прочие выполняющие роль CSS.

🔻 Не использейте <br> для разметки
Не используйте <br> для форматирования документа или для добавления отступов между элементами.
Это нужно делать с помощью margin или padding в CSS.

🔻 Не засоряйте код <div>ами и <span>ами
Семантические элементы HTML5 доступно описывают свой смысл или назначение как для браузеров, так и для веб-разработчиков.
Код

<div class=“main”>
  <div class=“menu”>
       <div class=“menu-item”>
         <div class=“image-wrapper”>
            <img src=“” alt=“”/>
            <div class=“image-description”></div>
         </div>
       </div>
  </div>
</div>


может быть заменен на более семантичный и читабельный

<main>
   <ul>
     <li>
         <figure>
             <img src=“” alt=“”/>
             <figcaption></figcaption>
         </figure>
     </li>
   </ul>
</main>


🔻 Избегайте непоследовательности
Если вы решили использовать 4 пробела или два таба для отступа, сделайте это на каждой строчке вашего HTML кода. Правило также касается регистра, кавычек и прочих элементов разметки кода. Делайте все в одном стиле.

🔻 Не используйте таблицы для блочной верстки
Таблици - только для таблиц. Исключение может быть только верстка emailов.

🔻 Не используйте спецсимволы (типа <, >, «, § и т д.)
Это ведет к невалидному коду.
Замените их на HTML мнемоники. Это это конструкция, которая ссылается на символ из набора символов текстового файла.
Например:
знак меньше < это &lt;
знак больше > это &gt;

🔻 Избегайте тегов <iframe> и <frame>
Их нужно использовать всего в нескольких случаях:
встраивание медиаконтента — как правило стороннего (видео с YouTube, пост с Facebook);
встраивание апплетов — приложений, работающих в контексте веб-сайта (формы оплаты или интерактивные карты)

🔻 Не используйте теги <script> без атрибута src и <style> без причины.
Есть кейсы в которых необходимо использовать эти теги, но в большинстве случев их можно вынести в оддельный файл, что поможет вам избавится от копипаста и поможет в дальнейшем переиспользовании.

🔻 Не вкладывайте блочные элементы в строчные
Строчные элементы могут содержать только данные и другие строчные элементы. Исключение составляет элемент <a>, который согласно спецификации HTML5 может оборачивать целые абзацы, списки, таблицы, заголовки и целые разделы при условии, что они не содержат другие интерактивные элементы - другие ссылки и кнопки.
источник
2019 July 31
WiseJS | Frontend tips
☑️ ВОПРОСЫ НА СОБЕСЕДОВАНИИ #2

🔻 1. Каким будет результат выполнения следующего кода?

const items = ["xyz", "xxxx", "test", “hello”, “qwe”];

delete items[3];
console.log(items.length);
// ?

Ответ:
console.log(items.length) // 5

💬 Пояснение:
Длина массива не изменится и будет равна 5. Если вывести в консоль массив items мы увидим следующее
["xyz", "xxxx", "test", undefined × 1,“qwe”]
Да, delete удаляет элемент из массива, но не так, как нам этого хочется. Образовалась «дырка».
Индексы элементов не изменились, и длина тоже.

🔻 2. Каким будет результат выполнения следующего кода?

function Foo(){}
Foo.prototype.bar = 42;

const foo = new Foo();

delete foo.bar;
console.log(foo.bar); // ?


Ответ:
console.log(foo.bar); // 42

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

delete Foo.prototype.bar; // удаляет свойство из прототипа
console.log(foo.bar); // undefined


🔻 3. Каким будет результат выполнения следующего кода?

a = 2;
delete a;
console.log(a); // ?



Ответ:
console.log(a); // undefined

💬 Пояснение:
Присвоение значения свойству без операторов var, const, let иногда неверно характеризуется, как глобальная переменная, (a = 2).
На самом деле происходит присвоение значения свойству глобального объекта. Оператор delete удалил поле a из обьекта window.

🔻 4. Каким будет результат выполнения следующего кода?

const a = 2;
delete a;
console.log(a); // ?


Ответ:
console.log(a); // 2

💬 Пояснение:
delete эффективен только применительно к свойствам объектов.
Он не оказывает никакого влияния на имена переменных и функций.

🔻 5. Каким будет результат выполнения следующего кода?

delete Math.PI;
console.log(Math.PI);  // ?


Ответ:
console.log(Math.PI);  // 3.1415…

💬 Пояснение:
delete не может удалить определенные свойства встроенных объектов (таких как Object, Array, Math и так далее)
источник