# Первый етап собеседования (в основном) # Браузер, additional - Что происходит от введение поисковую строку до отрисовки Когда пользователь вводит ссылку в поисковую строку браузера, происходит следующий процесс от запроса до отрисовки сайта: 1. Разбор URL и разрешение домена • Браузер парсит URL, выделяя протокол, домен и путь. • Проверяет кэш на наличие IP-адреса для домена. • Если в кэше нет, обращается к ОС для проверки файла hosts. • При отсутствии записи в hosts отправляет DNS-запрос для получения IP-адреса сервера. 2. Установка соединения и запрос HTML • Браузер устанавливает TCP-соединение с сервером по IP. • Отправляет HTTP-запрос на получение HTML-документа. • Сервер возвращает ответ с HTML в теле запроса. 3. Парсинг HTML и построение DOM • Браузер начинает читать HTML по мере поступления. • Построение DOM-дерева — внутренней структуры документа, где каждый HTML-элемент представлен узлом. • При встрече ссылок на внешние ресурсы (CSS, JS, изображения) браузер параллельно запрашивает их. 4. Парсинг CSS и построение CSSOM • Загруженные CSS-файлы парсятся в CSSOM — объектную модель стилей. • DOM и CSSOM объединяются для создания render tree — дерева рендеринга, которое содержит только видимые элементы с их стилями. 5. Layout (компоновка) • На этом этапе браузер рекурсивно вычисляет геометрию каждого элемента: размеры, положение (координаты X, Y) с учётом box model (margin, border, padding). • Layout начинается с корневого элемента и распространяется вниз по дереву рендеринга. • Этот процесс необходим, чтобы точно определить, где и как отображать элементы на экране. 6. Painting (отрисовка) • Браузер “рисует” каждый элемент на экране согласно layout и стилям. • Отрисовываются цвета, текстуры, шрифты, границы и другие визуальные свойства. • Этап painting преобразует абстрактные данные в пиксели на экране. 7. Compositing (композиция) • Для повышения производительности браузер разбивает страницу на слои. • Слои компонуются и выводятся на экран с помощью отдельного потока — compositor thread. • Это позволяет оптимизировать обновления и перерисовки. Дополнительно: Выполнение JavaScript • После загрузки и парсинга HTML и CSS браузер выполняет скрипты. • JavaScript может изменять DOM и CSSOM, что может вызвать повторные этапы layout и painting. • Скрипты обеспечивают интерактивность страницы. Таким образом, процесс от ввода ссылки до отображения сайта включает сетевые запросы, построение структур документа и стилей, вычисление расположения элементов, их отрисовку и компоновку на экране, а также выполнение скриптов для динамичности. - Трех этапное рукопожатие Трёхэтапное рукопожатие (3-way handshake) — это процесс установления надёжного TCP-соединения между клиентом и сервером, который обеспечивает синхронизацию и готовность обеих сторон к обмену данными. Как работает 3-way handshake? 1. SYN (Synchronize) Клиент инициирует соединение, отправляя серверу TCP-сегмент с установленным флагом SYN и случайным начальным номером последовательности. Это сигнал о желании начать соединение. 2. SYN-ACK (Synchronize-Acknowledge) Сервер получает SYN, резервирует ресурсы для нового соединения и отправляет ответный сегмент с флагами SYN и ACK. В этом сегменте сервер подтверждает получение SYN клиента и посылает свой собственный начальный номер последовательности. 3. ACK (Acknowledge) Клиент получает SYN-ACK, подтверждает его, отправляя серверу сегмент с флагом ACK. После этого соединение считается установленным, и начинается обмен данными. - JWT token types Access, ID, Refresh - WebRTC WebRTC (Web Real-Time Communications) — это открытая технология и стандарт для организации передачи аудио, видео и других данных напрямую между браузерами или приложениями в режиме реального времени без необходимости установки плагинов или дополнительного ПО. Она позволяет превратить браузер в полноценный терминал видеоконференций, обеспечивая двунаправленную (peer-to-peer) и защищённую коммуникацию с низкой задержкой. Для установления соединения используется сигнальный сервер и протоколы NAT Traversal (например, STUN), а управление происходит через JavaScript API. WebRTC широко применяется для видеозвонков, обмена файлами и текстовыми сообщениями прямо в браузере, упрощая создание интерактивных коммуникационных приложений Не является deprecated, но некоторые элементы улучшаются (Data channels на SCTP) ## Key points - P2P between browser (No need server) - UDP protocol (vety fast) - No built signaling - Not reliable protocol to transferring important data - We can combine WebRTC and WebSockets - Session Description Protocol (SDP) - Object that contains info about session connection (codec, address, media type etc.) - In connection one in form **OFFER** and one in form **ANSWER** - ICE Candidates (Interactive Connectivety Establishment) - Public IP that can be potentially used as address for receiveing data - STUN server (Session Traversial Utilities for NAT(Network Address Transition )) - WebSockets ## Keypoints - Permanent connection between client and server - Difference between Short Polling vs Long Polling ## Short Polling For example we have a client and Server. Client will make a call for data and wait for response. After response, client will wait for short period of time (for example 3 seconds) and than make this call again ### Key points - Bad design - You need to use client and server resoursec continuosly - Almost every time bad idea - Can use for prototype application very quickly ## Long Polling We still have client and server. Client initiating call to server and if server doesn’t have enough data yet, it’ll just keep this connection open for a period of time until data does arrive to client ### Key points - Tying up a connection between server and cliend (wasteful) - Good idea - local storage, Session storage, Cookie Вот краткая сравнительная таблица для sessionStorage, localStorage и cookies: | Характеристика | sessionStorage | localStorage | cookies | | --- | --- | --- | --- | | Объём хранения | ~5 МБ | ~5-10 МБ | До 4 КБ | | Срок хранения | Пока открыта вкладка (сессия) | Бессрочно, пока не удалены вручную | Задаётся при создании (может быть сессией или длительным) | | Доступность | Только в текущей вкладке браузера | Для всего домена (same origin) | Для домена, доступен и на клиенте, и на сервере | | Отправка на сервер | Нет | Нет | Да, при каждом HTTP-запросе | | Использование | Временное хранение данных сессии | Долговременное хранение данных | Хранение данных для сессий, аутентификации и передачи на сервер | | Поддержка | Современные браузеры (HTML5) | Современные браузеры (HTML5) | Все браузеры (старый стандарт) | - Спецификация в CSS Специфичность в CSS — это механизм, с помощью которого браузер определяет, какие CSS-правила применять к элементу, когда к нему подходит несколько правил. Она нужна для разрешения конфликтов, когда разные стили пытаются установить значения для одного и того же свойства элемента. Как вычисляется специфичность Браузер вычисляет специфичность каждого CSS-правила на основе типов селекторов, входящих в это правило. Селекторы оцениваются по категориям, которые можно представить как четырёхзначное число (A, B, C, D): • A — inline стили (например, `style="color: red;"`) . • B — ID селекторы (например, `#unique`) . • C — селекторы классов (например, `.example`), селекторы атрибутов (например, `type="radio"`) и псевдоклассы (например, `:hover`) . • D — селекторы тегов (например, `h1`) и псевдоэлементы (например, `::before`) . Чем больше значение, тем выше специфичность. Универсальный селектор (`*`), комбинаторы (`+`, `>`, `~`, ’ ’) и отрицающий псевдокласс (`:not()`) не влияют на специфичность, но селекторы внутри `:not()` учитываются - proto vs Prototype В JavaScript отличие между `__proto__` и `prototype` заключается в следующем: - `prototype` — это свойство функции-конструктора (или класса), которое является объектом и содержит методы и свойства, которые будут наследоваться объектами, созданными этой функцией через оператор `new`. У каждой функции есть своё свойство `prototype`, и именно оно используется при создании новых объектов для установки их прототипа[1][5]. - `__proto__` — это внутреннее (скрытое) свойство любого объекта, которое указывает на прототип этого объекта, то есть на объект, от которого он наследует свойства и методы. Фактически, `__proto__` — это ссылка на объект `prototype` функции-конструктора, с помощью которой был создан данный объект. Это свойство реализовано как геттер/сеттер и позволяет получить или изменить прототип объекта[1][3][5]. Иными словами: | Свойство | Что это | Кому принадлежит | Роль в наследовании | | --- | --- | --- | --- | | `prototype` | Объект-прототип функции | Функциям и классам | Хранит методы и свойства, которые наследуют создаваемые объекты | | `__proto__` | Ссылка на прототип объекта | Любому объекту | Указывает на прототип объекта, откуда он наследует | При создании объекта через `new` происходит установка `obj.__proto__ = Func.prototype` — то есть прототип объекта ссылается на `prototype` функции-конструктора[5][1]. Таким образом, `prototype` — это свойство функции, определяющее прототип для создаваемых объектов, а `__proto__` — это свойство объекта, указывающее на его прототип. Это ключевой механизм прототипного наследования в JavaScript[1][7][5]. - Clean Code - Code review - Prettier, Linters etc. - Solid - S - Single Responsibility - Ось изменения - переменные, которые постоянно меняются - Через класс должна проходить одна ось изменения (одна причина) - Что бы добиться, класс должен содержать только поля и методы, которые относятся к одному вопросу - Класс (Компонент) должен выполнять что-то одно - O - Open / Closed Principle - Любой блок ПО должен быть открыт для добавления функционала, но не изменяя существующую - Есть понятие Полиморфной модели - интерфейс должен оставаться неизменным для клиентской части, а реализация новой версии ПО дожна или наследовать старую, или делегировать (Боб Мартин) - Liskov Substitution Principle - Если у вас кусок кода, куда приходит базовый класс (Parent), то в этот же код должен свободно приходить его любой наследник - Interface Segregation Principle - Клиенты не должны зависить от метода, который они не используют - Не делать god interfece, который хранит все методы - Интерфейс преднадлежность клиента, не сервера - Dependency Inversion Principle - Модули верхних уровней не должны зависить от модулей нижних уровней (Оба от абстракции) - Детали должны зависить от абстракций - - DRY - KISS - YAGNI - Symbol use case **Unique Property Keys to Prevent Name Collisions** A primary and practical use case for JavaScript's **`Symbol`** is to create unique property keys for objects. In JavaScript, object property keys are typically strings, which can lead to naming collisions—especially in large projects or when integrating third-party libraries. By using symbols, you ensure that each property key is unique, even if the symbol descriptions are the same. This prevents accidental overwrites of properties and makes your code more robust - REST API methods - GET - POST - PUT - DELETE - PATCH - OPTIONS - HEAD - TRACE - SASS / SCSS ### **Що таке CSS-препроцесор?** **Відповідь:** CSS-препроцесор — це мова, яка компілюється в звичайний CSS і дозволяє використовувати змінні, вкладення, міксіни, функції тощо, щоб зробити стилі більш зручними, масштабованими та підтримуваними. --- ### **Яка різниця між SASS і SCSS?** **Відповідь:** - `SASS` (Syntactically Awesome Stylesheets) — старіший синтаксис з відступами (без фігурних дужок і крапок з комою). - `SCSS` — більш сучасний, схожий на звичайний CSS (із дужками `{}` та `;`), тому частіше використовується. > 💡 Вони обидва компілюються у CSS за допомогою sass компілятора. > --- ### **У чому різниця між SASS і LESS?** | Параметр | SASS/SCSS | LESS | | --- | --- | --- | | Синтаксис | SCSS ближчий до CSS | Теж схожий на CSS | | Компілятор | Dart Sass, node-sass | Вбудований у Node | | Підтримка логіки | Потужніша (if, @each) | Обмеженіша | | Популярність | Більш популярний | Менш активна підтримка | - Microfrontends  # **Микрофронтенд (Micro frontends)** Микрофронтенд (micro frontend) — архитектурный подход, в котором независимые приложения собраны в одно большое приложение. Он дает возможность объединить в одном приложении разные виджеты или страницы, написанные разными командами с использованием разных фреймворков (см. рис. ниже). [*Источник*](https://blog.pragmatists.com/independent-micro-frontends-with-single-spa-library-a829012dc5be) Главные преимущества микрофронтенд-подхода — в разработке больших энтерпрайз-приложений: - модульная архитектура. Отдельные виджеты или страницы — это полностью независимые приложения; - скорость тестирования. Изменения в одном виджете или странице можно протестировать изолированно и только в этом приложении, не тратя времени на тестирование всего остального функционала; - параллельные деплойменты. Отдельные виджеты или страницы могут и должны деплоиться независимо. Помимо очевидных достоинств такого подхода, у него есть и существенные недостатки: - увеличение общей сложности приложения; - дублирование кода. Каждое приложение разрабатывается отдельной командой, которая принимает свои технические решения. Это ведет к повторной загрузке одинаковых фреймворков, библиотек и общему дублированию кода, который мог быть использованным повторно; - JS-бандл монолитного приложения всегда будет меньше, чем совокупность бандлов в микрофронтенд-архитектуре; - возможные проблемы с кешированием и версионностью приложений; - глобальные переменные или CSS-стили — это вещи, о которых стоит забыть в микрофронтенд-архитектуре, если приложения полностью не изолированы. - Core Web Vitals - Tools to calculate - Google Lighthouse Detailed information about perfomance How to use? - DevTools → Lighthouse → Create analyz - PageSpeed Insights - Can give you pretty much that Lighthouse, but gives you side-by-side Mobile and Desktop analysis ### Core Web Vitals - LCP - Largest Contentful Paint - Reports the render time of the largest image or text block visible within the viewport, relative to when the user first navigated to the page - Unit - milliseconds - Needs improvement if it’s bigger than 2.5sec - FID - First Imput Delay (Deprecated since 09.09.2024) - Measures the time from when a user first interacts with a page to the time when the browser is actually able to begin processing event handlers in response to that interaction - Unit - milliseconds - Deprecated (Not Core now) → INP now core (Intercation to Next Paint) - INP - Interaction to Next Paint - CLS - Cumulative Layout Shift - Measures unexpected layout shifts that occur during the entire lifespan of a page. A layout shift occurs any time a visible element changes its position from one render frame to the next - Unit - - Needs improvement if it’s more than 0.1 - `layout shift score = impact fraction * distance fraction` - The [impact fraction](https://github.com/WICG/layout-instability#Impact-Fraction) measures how *unstable elements* impact the viewport area between two frames. - The *distance fraction* is the greatest horizontal or vertical distance any *unstable element* has moved in the frame, divided by the viewport's largest dimension (width or height, whichever is greater). ### Notable Metrics - TTFB - Time To First Byte - Measures the time between the request for a resource and when the first byte of the response begins to arrive - Unit - milliseconds - Total blocking time - Delay of the main thread - Web Perfomance Optimization Service worker is proxy between server and browser Global variable for jwt token render is async renderProp children api react - Server Side Perfomance Optimization JavaScript Все Типы данных включая new Map, new Set, Symbol, weakSet, weakMap There are 7 primitive data types: string, number, bigint, boolean, undefined, symbol, null Non-primitive Data Types: Object, Array Map is a key/value collection just like Object. But the main difference is that Map allows keys of any type, where each value can only appear once. A Set object is a special kind of collection: a "set" of values (without keys), where each value can only appear once. WeakMap is a Map-like collection that allows only objects to be used as keys, and automatically removes them, along with their corresponding values, as soon as they become otherwise unreachable. WeakSet is a Set-like collection that only stores objects and removes them as soon as they become otherwise unreachable. What WeekMap, WeekSet, WeekRef are? WeakMap is a Map-like collection that allows only objects to be used as keys, and automatically removes them, along with their corresponding values, as soon as they become otherwise unreachable. WeakSet is a Set-like collection that only stores objects and removes them as soon as they become otherwise unreachable. A WeakRef object lets you hold a weak reference to another object, without preventing that object from getting garbage-collected. A WeakRef object contains a weak reference to an object, which is called its target or referent. A weak reference to an object is a reference that does not prevent the object from being reclaimed by the garbage collector. In contrast, a normal (or strong) reference keeps an object in memory. When an object no longer has any strong references to it, the JavaScript engine's garbage collector may destroy the object and reclaim its memory. If that happens, you can't get the object from a weak reference anymore. Отличие между var, const, let var: Function scoped Undefined when accessing a variable before it's declared let: Block scoped ReferenceError when accessing a variable before it's declared Can be reassigned const: Block scoped ReferenceError when accessing a variable before it's declared Can't be reassigned Hoisting is a mechanism in JavaScript where variables and function declarations are moved to the top of their scope before the code is executed. when creating a VAR variable in JavaScript, it is initialized to undefined Что такое область видимости Scope is the accessibility zone of variables. Scopes can be nested A code block in JavaScript defines the scope of variables declared with the const and let keywords Functions in JavaScript create a scope for all variables, regardless of whether they are declared with the keyword var, const, or let. The global scope is the outermost scope. It is available to any internal or local scope. In the browser, the scope created globally when loading the JavaScript file specified in the src attribute of the script tag Event loop ( какие стеки бывают, обратить внимание на stack Animation, Promise, Timer ) Event Loop is a special mechanism at the js engine level that coordinates the work of three entities: Call Stack (call stack), Web API (API provided by the browser), Callback Queue (queue of callbacks). The event loop is the key to asynchronous JavaScript programming. The language itself is single-threaded, but using this mechanism allows you to create additional threads so that the code runs faster. The Event Loop moves the callback of the async function to the Web API, and the async function itself goes off the call stack. That is, while the callback of the asynchronous function is managed by the Web API, the js engine continues to perform other operations! The main task of event loops is to keep track of the stack and queue of tasks. If the stack is empty, the loop takes the first element from the queue, pushes it onto the stack, and executes. requestAnimationFrame https://developer.mozilla.org/ru/docs/Web/API/window/requestAnimationFrame cancelAnimationFrame https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame requestIdleCallback https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback cancelIdleCallback https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelIdleCallback IntersectionObserver https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API MutationObserver https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver Micro macro tasks Macrotasks include the main code that runs directly on the <script> element, event handlers, and code that is called on a timeout in setTimeout or setInterval. Microtasks include promises, Mutation Observer API events, and functions passed via queueMicrotask(). To add a new microtask to the queue: Use queueMicrotask(f). Promise handlers are also executed within the microtask queue. To add a new macro task to the queue: Use setTimeout(f)/setInterval with zero delay. Как работает Promise.all(), Promise.race(), Promise.allSettled(), Promise.any Promise.any() accepts multiple promises and returns the first successful promise. The Promise.all() function returns a single Promise object that concatenates a set of promises. The values of all promises are only returned if they all succeed. But if an error occurs in the asynchronous operation of at least one promise due to internal logic or due to a call to the reject () function, then all promises will go into the rejected state Promise.allSettled() just like Promise.all() takes a set of promises and executes them as a single unit, but returns an object with the status and result of the promise. If an error occurs, the status is rejected and the second property represents the error object. If the promise has successfully completed execution, then the status is fulfilled, and the second property - value stores the result of the promise. Promise.race() also accepts multiple promises, only returns the first completed promise (regardless of success or failure) setInterval, setImmediate, setTimeout, process.nextTick - какое отличие между ними By passing a function to the process.nextTick() method, we tell the system that this function should be called after the current iteration of the event loop has completed, before the next one begins. setTimeout allows you to call a function once after a certain time interval. setInterval allows you to call a function regularly, repeating the call after a certain time interval. setImmediate() will execute the code at the end of the current event loop. This code will run after any I/O in the current event loop and before any scheduled timers for the next event loop Which data types will be excluded from JSON.stringify result? JSON.stringify() is used to convert JavaScript values into a JSON string. However, not all data types are included in the resulting string. Here are the data types and values that will be excluded: ❌ Excluded or Ignored by JSON.stringify(): undefined Ignored in objects (key will be removed). Becomes null in arrays. JSON.stringify({ key: undefined }); // '{}' JSON.stringify([1, undefined, 3]); // '[1,null,3]' Functions Completely excluded in objects. Becomes null in arrays. JSON.stringify({ func: () => {} }); // '{}' JSON.stringify([1, function() {}, 3]); // '[1,null,3]' Symbols Ignored in both objects and arrays. JSON.stringify({ sym: Symbol("id") }); // '{}' JSON.stringify([1, Symbol("id"), 3]); // '[1,null,3]' Non-enumerable properties Not included even if the type is valid. const obj = {}; Object.defineProperty(obj, 'hidden', { value: 123, enumerable: false }); JSON.stringify(obj); // '{}' Circular References Will throw a TypeError if not handled. const obj = {}; obj.self = obj; JSON.stringify(obj); // TypeError: Converting circular structure to JSON ✅ Included by JSON.stringify(): Strings Numbers (except NaN and Infinity, which become null) Booleans null Arrays Plain objects Date objects (converted to ISO string) Other JSON-safe values Reduce, ReduceRight Reduce - this method takes a function that takes an accumulator and a value as an argument. It applies a function to the accumulator and each array value to return only one value as a result. The reduceRight() method applies a function to the accumulator and each array value (from right to left), reducing it to a single value. How to place link essence into object key? JSON.stringify or Symbol Which JS key / value essence automaticaly sorts keys? ✅ Objects ({}) automatically sort numeric keys but preserve the insertion order for strings and symbols. ❌ Maps (new Map()) do NOT sort keys automatically; they maintain the original insertion order. Example: const obj = { 3: 'three', 1: 'one', 2: 'two', 'b': 'bee', 'a': 'ay' }; console.log(obj); What CharCodes are? What the role of charcodes in javascript ecosystem? 🔤 What are CharCodes? CharCodes in JavaScript refer to the numeric values that represent characters, based on Unicode encoding. Each character (like 'A', '1', '@', '中', etc.) corresponds to a specific code point, and JavaScript lets you work with these numbers using: String.charCodeAt(index) — gets the code of a character at a specific position. String.fromCharCode(code) — creates a string from a code. "A".charCodeAt(0); // 65 String.fromCharCode(65); // "A" These are usually UTF-16 code units, which means most common characters are represented by a single 16-bit number. 🧩 Role of CharCodes in JavaScript CharCodes are useful and important for several reasons in the JS ecosystem: ✅ 1. Text Processing & Comparison CharCodes help compare characters numerically, sort them, or filter by type: function isUpperCase(char) { const code = char.charCodeAt(0); return code >= 65 && code <= 90; // 'A' to 'Z' } ✅ 2. Encoding and Decoding When dealing with data at the byte/character level (e.g., Base64, file processing, network data), you often work with CharCodes. ✅ 3. Custom Algorithms In algorithms (like ciphers, hashing, validation), char codes let you manipulate characters efficiently: function caesarCipher(str, shift) { return str .split('') .map(char => { let code = char.charCodeAt(0); if (char >= 'A' && char <= 'Z') { return String.fromCharCode(((code - 65 + shift) % 26) + 65); } return char; }) .join(''); } ✅ 4. Internationalization & Unicode Handling JavaScript supports Unicode, and working with characters outside the Basic Multilingual Plane (like emojis or rare scripts) requires understanding code points and surrogate pairs: const emoji = '💙'; emoji.charCodeAt(0); // 55357 (high surrogate) emoji.charCodeAt(1); // 56489 (low surrogate) To handle full code points: emoji.codePointAt(0); // 128153 String.fromCodePoint(128153); // '💙' 🧠 TL;DR CharCodes are numeric representations of characters. Used for low-level character operations: sorting, encoding, algorithms, validation. They're key when working with Unicode, especially for complex or non-English characters. How many concurrent requests per domain per second a web browser allows to send? Modern browsers enforce limits on the number of simultaneous HTTP connections to a single domain. This is typically between 6 to 13 concurrent requests per domain. Что такое promise, yield, в чем их отличие Promise is used for deferred and asynchronous calculations. Promise can be in three states: pending: initial state, not executed or rejected. fulfilled (fulfilled): The operation completed successfully. rejected: The operation ended with an error. The yield keyword is used to stop and resume generator functions The yield keyword returns an object with two parameters, value and done. In this case, value is the result of evaluating the expression after yield, and done indicates whether the generator function was completed. async / await There is a special syntax for dealing with promises called "async/await". The word async has one simple meaning: this function always returns a promise. Values of other types are wrapped in a successful promise automatically. The await keyword will cause the JavaScript interpreter to wait until the promise to the right of await is fulfilled. After that, it will return its result, and code execution will continue. Деструктуризация массивов/объектов Destructuring assignment is a special assignment syntax in which you can assign an array or object to several variables at once, breaking it into parts. Разница между spread и rest оператором The rest operator allows you to represent an indefinite number of arguments as an array. Unlike the spread operator, which extracts the elements of an array, the rest operator (or, as it is also called: the collection operator) groups many elements into one array. The spread operator extracts the elements of an array, The rest operator collects elements (such as function arguments) into an array. Что такое getter / setter Властивості аксесори These are accessor properties. At their core, these are functions that are used to set and receive a value, but in external code they look like ordinary object properties. Accessor properties are represented by methods: "getter" - for reading and "setter" - for writing. When an object is declared literal, they are denoted by get and set: Getters/setters can be used as wrappers over "real" property values to give you more control over operation with them. Зачем нужен prototype у объектов и функций When we want to read a property from object and it's missing, JavaScript automatically takes it from the prototype. In programming, this mechanism is called "prototype inheritance” In JavaScript, all objects have a hidden [[Prototype]] property, which is either another object or null. Prototypes are the mechanism by which JavaScript objects inherit properties from each other. If we call obj.method(), and the method is taken from the prototype, then this still refers to obj. Thus, methods always work on the current object, even if they are inherited. The for..in loop iterates over both its own and inherited properties. The remaining methods for obtaining keys/values work only with the object's own properties. What the difference between proto and prototype? 🔍 __proto__ vs prototype Concept __proto__ prototype Type A property of objects A property of constructor functions Purpose Points to the object's prototype (its internal inheritance link) Used to define what will be inherited by instances Who has it? Every object Every function (because functions are objects too) Used for? Reading an object's inheritance chain ([[Prototype]]) Setting up inheritance when using new ✅ Example Time: function Animal() { this.legs = 4; } // This sets up what new objects created with `new Animal()` will inherit from: Animal.prototype.speak = function() { return "I make a sound"; }; // Creating a new object: const dog = new Animal(); console.log(dog.__proto__ === Animal.prototype); // true ✅ console.log(dog.speak()); // "I make a sound" Breakdown: Animal.prototype: this is the template that will be assigned to all instances created using new Animal(). dog.__proto__: this points to Animal.prototype. 🧬 Inheritance Chain When you access a property on dog, like dog.speak, JavaScript looks: Is it on dog directly? If not → follow dog.__proto__ → which is Animal.prototype. If not found there → follow its __proto__, and so on. That’s prototype chain lookup. ⚠️ Important Notes __proto__ is deprecated, but still widely used and supported. Prefer Object.getPrototypeOf(obj) for clean code. Don’t confuse: obj.__proto__ // → The internal [[Prototype]] of obj Function.prototype // → The object that instances of a function will inherit from 🧠 Summary Feature __proto__ prototype Belongs to All objects Constructor functions Points to The actual prototype of the object The object that becomes the prototype of instances Used in Inheritance lookup Defining instance behavior new Event зачем нужен и как использовать The Event interface represents any event that occurs in the DOM; some of them are user-generated (mouse click or keyboard keystroke), and some are API-generated (events indicating the end of the animation process, pause the video, etc.). There are many types of events, some of them use interfaces based on the main Event interface. Event contains common properties and methods for all events. The event object is always passed to the handler and contains a lot of useful information about where and what event happened. The new Event command is an event constructor that can be used to create an event object and then call that event from JavaScript using the dispatchEvent() method What is EventBus? 🚍 What is an Event Bus? An Event Bus is a central communication system that allows different parts of an application to send and receive messages (events) without being directly connected to each other. Think of it like a radio station: components can broadcast messages, and other components can tune in and react — without either side knowing who the other is. ✅ Why Use an Event Bus? To enable decoupled communication between components To keep code cleaner and more modular To avoid prop drilling or deep callback nesting Often used in component-based frameworks (React, Vue, Angular, etc.) 🔧 Simple Example (Vanilla JS) const EventBus = { events: {}, on(event, callback) { if (!this.events[event]) this.events[event] = []; this.events[event].push(callback); }, emit(event, data) { if (this.events[event]) { this.events[event].forEach(cb => cb(data)); } }, off(event, callback) { if (this.events[event]) { this.events[event] = this.events[event].filter(cb => cb !== callback); } } }; // Listener EventBus.on('userLoggedIn', (user) => { console.log('Welcome,', user.name); }); // Emit an event EventBus.emit('userLoggedIn', { name: 'Alice' }); 📦 Event Bus in Frameworks 🔹 React React doesn’t have a built-in event bus, but you can use: Custom event bus with EventEmitter (like in Node.js) Context API or Redux (preferred in larger apps) 🧠 TL;DR Event Bus = a messaging system inside your app Allows loose coupling: parts of your app can communicate without knowing about each other Great for global events, like authentication, notifications, or syncing components What is EventEmmiter? 🔊 What is EventEmitter? EventEmitter is a core module in Node.js that allows you to: Emit events (send/broadcast) Listen to events (subscribe/react) Think of it like a built-in event bus for Node.js. 🔧 Why Use EventEmitter? It's useful when: You want different parts of your app to communicate asynchronously You're building systems like chat apps, logging services, file watchers, etc. 📦 Where does it come from? It's part of the events module in Node.js: const EventEmitter = require('events'); You create an instance, and then you can emit and listen to events. ✅ Simple Example const EventEmitter = require('events'); const myEmitter = new EventEmitter(); // Listener myEmitter.on('greet', (name) => { console.log(`Hello, ${name}!`); }); // Emit event myEmitter.emit('greet', 'Alice'); // Output: Hello, Alice! 🔁 Common Methods Method Description .on(event, fn) Listen to an event .emit(event, data) Trigger an event with optional data .once(event, fn) Listen to an event only once .removeListener() Remove a listener .off() Alias for removeListener (Node v10+) 🧠 Under the Hood Use You’ll see EventEmitter used in many built-in Node modules like: http.Server → emits 'request' events fs.ReadStream → emits 'data', 'end', 'error' process → emits 'exit', 'uncaughtException', etc. process.on('exit', () => { console.log('Goodbye!'); }); ⚠️ Notes EventEmitter is synchronous by default (handlers run in order when emit() is called). You can create custom classes that inherit from EventEmitter: class MyLogger extends EventEmitter { log(message) { console.log('LOG:', message); this.emit('logged', message); } } const logger = new MyLogger(); logger.on('logged', msg => console.log('Event caught:', msg)); logger.log('Hello world'); 🧠 TL;DR Feature Description What Built-in class for event handling Where Node.js core module: require('events') Key methods .on(), .emit(), .once() Use case Decoupled communication in Node apps How to send data from a website to an Iframe and vice versa? PostMessage (BroadcastAPI) How to share data between browser tabs? Subscribe for local storage BroadCast Channel API How GC (garbage collector) works? 🧹 What is a Garbage Collector? The garbage collector (GC) is an automatic memory management feature in JavaScript engines (like V8 in Chrome/Node.js). It frees up memory by removing data that is no longer "reachable" or needed by your program. 🧠 Basic Idea JavaScript automatically allocates memory when you create things (like variables, objects, arrays) and reclaims it when it’s no longer used. You don’t need to free() memory manually (like in C/C++). 🔍 How It Knows What to Delete? The GC uses a concept called reachability. If something is reachable (accessible or usable) → it stays. If something becomes unreachable → it gets deleted. ✅ What Is Considered Reachable? Reachable means the object can be accessed in some way: From a root, like: Local variables in a function currently executing Global variables Function parameters and closures Anything referenced by reachable objects 📦 Example: let person = { name: "Alice", friend: { name: "Bob" } }; // Both objects are reachable here. If later: person = null; Now: The person object is gone The nested friend object becomes unreachable too → GC will clean them both ♻️ How Garbage Collection Works (Behind the Scenes) 📌 1. Mark-and-Sweep Algorithm (Most common) GC starts at roots (global variables, function scopes) It follows references to mark everything reachable Anything not marked is swept away (freed) 🧪 Example: function test() { let a = { value: 1 }; let b = { value: 2 }; a.next = b; b.prev = a; } // After test() finishes, both a and b are out of scope → collected. 🧠 Other Optimizations Modern JS engines use smarter strategies like: Generational GC: newer objects are collected more frequently Incremental GC: splits work into chunks to avoid app freezing Idle-time GC: runs when CPU is free ⚠️ Common Memory Leaks Even with GC, you can still leak memory if: You keep references you don’t need: let cache = {}; cache['user'] = largeObject; // never cleared Global variables that never get removed Event listeners that aren’t cleaned up Closures holding onto outer scope 🔧 Tools to Debug Memory Chrome DevTools → Memory tab: snapshot & analyze heap Node.js → --inspect, global.gc() (when enabled) Libraries: leakage, memwatch, etc. ✅ TL;DR Concept Explanation What is GC? Automatic memory cleanup in JS How it works? Removes objects that are unreachable Key algorithm Mark-and-sweep You still leak? Yes, if you keep unnecessary references What the difference between Function and Arrorw function? ⚔️ Function vs Arrow Function — Key Differences Feature function => Arrow Function Syntax function sayHi() {} const sayHi = () => {} this context Dynamic (depends on caller) Lexical (inherits from outer scope) Can be used as constructor? ✅ Yes (new MyFunc()) ❌ No — throws error arguments object ✅ Available ❌ Not available super and new.target ✅ Supported ❌ Not supported Hoisting ✅ Yes (function declarations) ❌ No (must be defined first) 🔍 1. this Binding (Most Important Difference!) ✅ Traditional Function const person = { name: 'Alice', sayHi: function () { console.log('Hi,', this.name); // `this` points to `person` } }; person.sayHi(); // Hi, Alice ❌ Arrow Function const person = { name: 'Alice', sayHi: () => { console.log('Hi,', this.name); // `this` is NOT `person`, it's inherited from outer scope } }; person.sayHi(); // Hi, undefined (in browser, this = window) 🧠 Arrow functions do not have their own this — they inherit it from where they are defined (not called). 🔍 2. arguments Object function showArgs() { console.log(arguments); } showArgs(1, 2, 3); // [1, 2, 3] const arrowArgs = () => { console.log(arguments); }; arrowArgs(1, 2, 3); // ❌ Error: arguments is not defined 🔍 3. Constructors function Car() { this.brand = 'Toyota'; } const myCar = new Car(); // ✅ works const CarArrow = () => { this.brand = 'Toyota'; }; const myArrowCar = new CarArrow(); // ❌ TypeError: CarArrow is not a constructor 🧠 When to Use Which? Use Case Recommended Function Type Object methods Regular function Callbacks, event handlers Depends, but regular often better for this Short logic or inline functions Arrow function Inside .map(), .forEach() Arrow function Constructor or class method Regular function ✅ TL;DR Arrow functions are shorter, inherit this, and don’t have their own arguments, super, or new.target. Regular functions are more flexible and better when you need dynamic this, hoisting, or use as constructors. Почему typeof null возвращает object This bug will probably never be fixed due to the need to keep existing code backwards compatible with new versions of the language. В чем отличие null и undefined null has two features that we need to emphasize: null indicates that the variable is "empty"; null must be assigned. undefined usually means that the variable is declared but has not been assigned a value. Or when looking for non-existent object properties you will get undefined null is not strictly equal to undefined strict comparison null != undefined // returns false In arithmetic operations null is converted to 0 and undefined returns NaN Что такое контекст this? Как работает this is a keyword in JavaScript that contains the object (context) of the code being executed. this is a unique variable that stores the context of the executable code. Conversely, the context is the value of the this keyword. In most cases, the value of this is determined by how the function is called. The value of this cannot be set by assignment at runtime and may have a different value each time the function is called. call, bind, apply The call() method calls a function with the given context. In other words, you bind a function to an object as if it belonged to it. The apply() method is similar to call(). The only difference is that call() takes a list of arguments, while apply() takes an array. The bind() method works in a similar way to call() and apply(), but unlike them, it returns a function call of which can be deferred. RegExp Regular expressions (also called regexp, or regex) are a mechanism for finding and replacing text. In a line, a file, several files... They are used by developers in the application code, by testers in autotests, or simply when working on the command line! Regular expressions allows you to set a template. Классы In JavaScript, a class is a kind of function. The "class" construct, which provides new features useful for object-oriented programming. When new ClassName("some parameters") is called: A new object is created. Constructor is run with the given argument and stores it in this.parameterName. TypeScript After fundamental course: Проблематика (зачем нужен) JS == слабая и динмическая типизация Что означает слабая и динамическая? Слабая JS позволяет работать с разными типами, при этому неявно преобразуя их (type coercion) console.log("10" - 2) // число console.log("10" * "2") // число console.log("10" / 2) // число console.log("10" + 2) // строка Динмаческая Тип определяется в рантайме (во время выполнения програмы), а не на этапе компиляции и написания кода let variable = 5; variable = '5'; variable = {username: 'Pavlo'} // Выше мы меняем тип переменной на каждой строчке кода function fn(data) { if(data) { return 'string' } else { return 777; } } // Во втором примере мы возращаем тип условно (в зависимости есть ли данные) Проблемы Сложность в поддержке больших проектов (есть данные, нет описания) На этапе написание кода отлавливать проблемы с типами приходиться в голове Усложняется дебаг и тестирование кода Усложняется анализ кода разработчиком Отстутствие адекватного автокомплита в среде разработки Что такое TS? TypeScript - это надмножество над JS (содержит в себе все, что есть в JS, но расширяет его). Мы работаем с такими же примитивами и на основе их строим более сложные структуры. TS - язык программирования со статической типизацией (явной или выводимой) Статическая компиляция (+ явная и выводимая компиляция) Статическая компиляция - когда типы проверяются на этапе компиляции, а не выполнения Пример явной типизации let variable: number = 5; // <- здесь мы явно указываем тип Пример выводимой типизации let variable = 5 // <- здесь тип присваивается сам Пример структурной типизации type User = { firstname: string, lastname: string, } // Взаимозаменемые type Person = { firstname: string, lastname: string, } Types variants Составные типы Примитивы Специальные типы Generic types Literals const color = "red" | "green" Unions / Intersactions Special types any unknown never void literals Union types Обозначает объединение множеств (типов) let data: number | string; // Дата может быть ИЛИ число ИЛИ строка data = 5 data = 'string' Более сложный пример type MainInfo = { firstname: string, lastname: string, } type AdditionalInfo = { age: number, } type FullInfo = MainInfo | AdditionalInfo // Объединение типов const info1: FullInfo = { firstName: 'First', lastname: 'Info', } // Мы использовали только первый тип const info2: FullInfo = { age: 20 } // Мы использовали только второй тип const info3: FullInfo = { firstName: 'First', lastname: 'Info', age: 21, } // Мы использовали и первый, и второй типы Intersection types Мы можем использовать только поля, которые есть в обоих типах Пример: type MainInfo = { firstname: string, lastname: string, } type AdditionalInfo = { age: number, } type FullInfo = MainInfo & AdditionalInfo // Объединение типов const info1: FullInfo = { firstname: 'First', lastname: 'Info', } // Ошибка, не хватает age const info2: FullInfo = { age: 20 } // Ошибка, не хватает firstname и lastname const info3: FullInfo = { firstname: 'First', lastname: 'Info', age: 21, } // Сработало! Super types and Sub types Пример type SuperType = { name: string; } type SubType = { name: string; age: number; } What are Enums in TypeScript, and when should you use them? Enums are a way to define a set of named constants. enum Direction { Up, Down, Left, Right } 🔸 Use enums to represent a fixed set of options like status codes, directions, roles, etc. What is the difference between interfaces and types in TypeScript? Both can define shapes of objects, but: Feature interface type Extension Can be extended Can extend using intersection (&) Merging ✅ Yes (declaration merging) ❌ No Usage Object shapes only Can alias primitives, unions, etc What are generics in TypeScript, and what advantages do they provide? Generics let you create reusable components that work with any type. function identity<T>(value: T): T { return value; } ✅ Advantages: Type safety + reusability. How do you create and use namespaces in TypeScript? Namespaces group related code. namespace MathUtils { export function add(x: number, y: number): number { return x + y; } } Call with: MathUtils.add(2, 3) 📝 Use mainly in non-module codebases (not with ES modules). What are decorators in TypeScript, and what are some use cases for them? Decorators are functions that modify classes, methods, or properties. function Log(target: any, name: string) { console.log(`Called ${name}`); } class Person { @Log greet() {} } 📌 Use cases: logging, validation, What is the difference between the "any" and "unknown" types in TypeScript? any: Turns off all type checking. unknown: Safer; must be checked or cast before use. let val: unknown = 10; // val.toFixed(); ❌ must check or cast first What are mapped types, and how can they be used in TypeScript? Create new types based on existing ones. type Readonly<T> = { [K in keyof T]: T[K]; }; Great for transforming shapes like making all properties optional or readonly. How do you create and use index signatures in TypeScript? Allow dynamic keys with specific value types. interface StringMap { [key: string]: string; } What is the difference between "readonly" and "const" in TypeScript? readonly vs const readonly: Used for object properties (compile-time immutability). const: Used for variables (prevents reassignment). const x = 10; readonly name: string; How do you implement inheritance and polymorphism in TypeScript? Using extends for classes/interfaces and method overriding. class Animal { speak() {} } class Dog extends Animal { speak() { console.log("Bark"); } } How do you use the "keyof" and "typeof" type operators in TypeScript? keyof: Gets keys of a type. typeof: Gets type of a variable. type Person = { name: string; age: number }; type Keys = keyof Person; // 'name' | 'age' const person = { name: "A" }; type PersonType = typeof person; What are conditional types, and how can they be used in TypeScript? Types that depend on a condition. type IsString<T> = T extends string ? true : false; How do you handle overloading function signatures in TypeScript? Define multiple signatures. function add(x: number, y: number): number; function add(x: string, y: string): string; function add(x: any, y: any): any { return x + y; } Can you explain the concept of type narrowing in TypeScript? Refining a type using checks. function print(val: string | number) { if (typeof val === 'string') { // now it's string } } How do you create and use tuple types in TypeScript? Fixed-size, typed arrays. let tuple: [string, number] = ['hello', 42]; What is the difference between type aliases and interfaces in TypeScript? Use type for primitives/unions/intersections. Use interface for extending and declaration merging. How do you define optional and required properties in TypeScript interfaces? interface User { name: string; age?: number; // optional } What is the "never" type in TypeScript, and when would you use it? Used for unreachable code or functions that never return. function fail(): never { throw new Error(); } How do you handle null and undefined values in TypeScript types? Use union types: let val: string | null | undefined; Use strictNullChecks to force safe checks. How do you handle type assertions in TypeScript? Tell TypeScript you know the type: const val = someValue as string; // or const val = <string>someValue; How do you create and use union and intersection types in TypeScript? Union: A | B (either A or B) Intersection: A & B (both A and B) What is the difference between the "as" and "angle-bracket" syntax for type casting in TypeScript? Both are for type casting: const val = someValue as string; // preferred in TSX/React const val = <string>someValue; How do you use ambient declarations and declaration merging in TypeScript? Ambient: Declare types for external libs (.d.ts files). Merging: Interfaces with same name merge. declare module "express" { ... } How do you configure a TypeScript project using the tsconfig.json file? Configures the TypeScript compiler (e.g. target, module, strict mode, paths, etc.) { "compilerOptions": { "strict": true, "target": "ES6" } } How do you work with strict mode in TypeScript, and what benefits does it provide? Enables strict type checks. "strict": true Benefits: Better type safety Fewer runtime errors Safer null handling





0 reviews
| 5 | 0 | ||
| 4 | 0 | ||
| 3 | 0 | ||
| 2 | 0 | ||
| 1 | 0 |
Active users
0
All-time users
0
Favorites
0
Last updated
8 months ago
Date created
Feb 17, 2026
