JavaScript Flashcards
- Які типи даних присутні в JavaScript?
Існує 8 типів даних. 7 примітивних та 1 складний тип даних.
Примітивні типи: number, string, boolean, symbol, bigInt, null, undefined.
Складний тип - object. Він використовується для колекцій даних та для оголошення більш складних сутностей. Також він передається за посиланням, а прості типи даних за значенням.
- Що таке NaN?
NaN (not a number) - це значення, що отримується в результаті виконання числової операції над не числовим значенням. Його тип даних number. NaN не дорівнює самому собі.
Перевірку на NaN можна зробити за допомогою Number.isNaN
- Яка різниця між null та undefined?
undefined (невизначений) являє собою значення за замовчуванням:
1 - змінної, яку оголосили без ініціалізації;
2 - функції, яка нічого не повертає явно;
3 - неіснуючої властивості об’єкта. null - це значення «відсутності значення».
Присвоюється змінній явно.
- Чим відрізняється строга і нестрога рівність (=== та ==)?
Строга рівність порівнює значення за типом даних та значенням. Нестроге приводить значення до одного типу, а потім ці значення порівнює.
- Чому результатом порівняння двох схожих об’єктів є false?
Тому що об’єкти - це типи даних, що передаються за посиланням. 2 однакові на вигляд об’єкта мають різні посилання, і тому операція порівняння повертатиме false.
- Як перевірити 2 об’єкти на ідентичність?
1 - використовувати JSON.stringify для приведення об’єктів у рядок та порівняти їх вже як 2 рядки. Такий підхід має обмеження. Якщо в об’єкті будуть методи або symbol - JSON.stringify не зможе конвертувати їх у рядок.
2 - написати або використати з бібліотеки функцію deepEqual, яка буде проходити циклом по ключах двох об’єктів і перевірятиме значення цих ключів. Функція має працювати рекурсивно.
- Як зробити копію об’єкта?
Існує поняття глибокого та поверхневого копіювання. Глибоке - це копіювання об’єкта та всіх його рівнів вкладеності. Поверхневе - це копіювання лише першого рівня вкладеності, а для решти копіюється посилання.
Способи поверхневого копіювання:
1 - використовувати spread оператор (…)
2 - використовувати Object.assign()
Способи глибокого копіювання:
1 - використовувати JSON.stringify - JSON.parse для конвертування об’єкта в рядок і потім назад. Має обмеження щодо копіювання методів та symbols
2 - написати або використати з бібліотеки функцію deepClone яка буде рекурсивно проходитиме за ключами об’єкта та копіюватиме їх у новий об’єкт.
- Чим відрізняються змінні var, let та const?
var - змінну можна ініціалізувати після оголошення, можна змінювати, має функціональну область видимості, має hoisting. Зараз майже не використовують під час написання нового коду.
let - змінну можна ініціалізувати після оголошення, можна змінювати, має блокову область видимості, не має hoisting.
const - змінну обов’язково потрібно ініціалізувати під час оголошення, не можна змінювати, має блокову область видимості, не має hoisting.
- Як дізнатися чи є об’єкт масивом?
Для цього можна використати метод Array.isArray.
- Які перебираючі методи масивів ви знаєте?
Є такі методи:
- forEach – для перебору масиву.
- filter – для фільтрації масиву.
- every/some – для перевірки масиву.
- map – для трансформації масиву в масив.
- reduce/reduceRight – для проходу по масиву з обчисленням значення.
- sort - сортує масив.
- Як об’єднати масиви?
1 - Можна використовувати метод concat().
2 - Можна використовувати spread оператор та об’єднати ці масиви в один загальний масив.
- Як дізнатися чи знаходиться елемент у масиві?
1 - Використати метод includes, який повертає true якщо елемент знаходиться у масиві.
2 - Використати метод indexOf, який повертає індекс знайденого елемента в масиві або -1 якщо елемента в масиві немає.
3 - також можна використати метод find, який повертає знайдений елемент, або повертає undefined.
- Що таке підняття (hoisting)?
Це механізм у JavaScript, в якому змінні та оголошення функцій, пересуваються вгору своєї області видимості перед тим, як код буде виконаний. Піднімаються змінні типу var та function declaration.
- Яким буде значення змінної var, якщо звернутися до неї до її оголошення?
Значенням змінної буде undefined.
- Що буде, якщо звернутися до змінної let/const до її оголошення?
Буде помилка типу ReferenceError. Змінної ще не існує
- Що таке область видимості (Scope)?
Це місце, де (або звідки) ми маємо доступ до змінних або функцій. JS має 4 типи областей видимості: глобальна, функціональна, блокова (ES6) та область видимості eval.
- Чим Function Declaration відрізняється від Function Expression?
Function Expression створюється, коли виконання доходить до нього, а потім вже може використовуватися.
Function Declaration можна використовувати у всьому скрипті (або блоці коду, якщо функцію оголошено в блоці).
- Чим стрілочна функція відрізняється від звичайної?
1 - Стрілочна функція не має власного this. Вона бере його за місцем створення. У звичайній функції this визначається під час виклику.
2 - Стрілочна функція не має arguments.
3 - Стрілочна функція не має prototype.
4 - Стрілочна функція має короткий синтаксис неявного повернення значення.
- Чи існує аналог arguments для стрілочної функції?
Аналога немає. Але можна використовувати rest оператор (…) для того, щоб зібрати всі параметри з якими викликана функція в масив.
- Що таке лексичне оточення (Lexical Environment)?
Це властивості внутрішнього об’єкта функції, які створюються під час її виклику. Туди записуються аргументи, функції та змінні. Також там знаходиться посилання на зовнішнє лексичне оточення.
- Що є глобальним лексичним оточенням?
У несуворому режимі це window. У суворому - undefined.
- Що таке замикання (Closures)?
Це здатність функції під час створення запам’ятовувати посилання на змінні, функції та параметри, що знаходяться в поточному лексичному оточенні, а також у лексичному оточенні батьківської функції й так до глобального лексичного оточення.
Замикання передбачає саме зовнішні змінні, а не саму функцію.
- Для чого використовують замикання?
1 - Часто для створення приватних змінних та функцій (інкапсуляція).
2 - Для збереження проміжних параметрів виклику функції (каррування).
- Що таке IIFE?
Immediately Invoked Function Expression - це функція, яка викликається або виконується одразу після створення або оголошення.
- Що таке this?
Це посилання на контекст виклику функції. Контекстом є об’єкт, який в цей момент виконує або викликає функцію. Для стрілочної функції — це об’єкт у якому вона створена, а у звичайній функції — яким вона викликана.
Контекстом може бути:
1 - this в об’єкті — вказує на сам об’єкт
2 - this в класі — вказує на екземпляр класу
3 - глобальним контекстом є window (або undefined в режимі use strict).
- Як можна підмінити контекст виклику функції?
Є 3 методи: call, apply, bind. call та apply викликають функцію із заданим контекстом. bind повертає нову функцію із вже назавжди прив’язаним контекстом.
- Чи можна змінити контекст функції, яку повернув метод bind?
Ні, bind прив’язує контекст назавжди.
- Чи можна підмінити контекст виклику стрілочної функції?
Ні. Стрілочна функція не має методів call, apply, bind і своїх аналогів. Також вона використовує контекст у якому її створили, а не контекст у якому її викликали.
- Що таке прототип об’єкта?
Це шаблон об’єкта. Він використовується як запасний варіант для властивостей та методів, що існують у цьому об’єкті. Це також один зі способів обміну властивостями та функціональністю між об’єктами. Це основна концепція прототипного наслідування в JS.
- Як працює прототипне наслідування в JavaScript?
Коли ми хочемо прочитати властивість з об’єкта, а вона відсутня - JavaScript спробує прочитати його з прототипу об’єкта.
Якщо властивості немає в прототипі, JavaScript намагатиметься його прочитати з прототипу прототипу, і т.д. доки властивість не буде знайдено або ланцюжок прототипів не закінчиться. У такому разі JavaScript поверне undefined.
- Як створити об’єкт у якому не буде прототипу?
Використати Object.create(). Цей метод приймає першим аргументом об’єкт, який буде прототипом об’єкта, який він поверне. Якщо ми викличемо Object.create() з аргументом null, буде створено об’єкт без прототипу.
- Як перевірити чи є властивість об’єкта особистою властивістю або це властивість прототипу?
Можна використовувати метод hasOwnProperty, який повертає true або false, в залежності від того, чи містить об’єкт зазначену властивість, як власну властивість, чи ні.
- Як заборонити змінювати об’єкт?
1 - Є метод Object.freeze(), який ““заморожує”” об’єкт від змін. Цей метод працює тільки в один бік. Скасувати дію цього методу вже неможливо.
2 - Є метод Object.seal(), який забороняє додавати нові властивості, але вже наявні властивості можна змінювати.
3 - Також є метод Object.preventExtensions(), який забороняє додавати нові властивості в об’єкт.
- Що таке дескриптори властивостей об’єкта?
Дескриптор — це об’єкт конфігурації властивості в об’єкті.
Він має 4 властивості:
- value - значення властивості об’єкта,
- writable - вказує чи можна змінювати значення цієї властивості,
- enumerable - вказує чи буде видно властивість під час перебору властивостей об’єкта,
- configurable - вказує чи можна додавати або видаляти властивості об’єкта, а також чи можна змінювати дескриптори його властивостей.
- Чим відрізняється функція конструктор та клас?
Клас — це синтаксичний цукор над функцією конструктора. Під час створення екземпляра класу, методи описані в ньому потрапляють у прототип, а методи описані всередині функції конструктора потраплять у сам екземпляр. Для того, щоб методи, описані всередині функції конструктора, потрапили в прототип, їх потрібно окремо туди додати.
- Що потрібно зробити, щоб метод класу потрапив до його екземпляра?
Такий метод слід описати всередині конструктора.
- Чи є в JavaScript множинне наслідування?
Ні, тому що наслідування в JavaScript базується на прототипах, а в одного об’єкта може бути лише один прототип.
- Що таке Promise?
Це об’єкт, який використовують для відкладених та асинхронних обчислень.
Promise має 3 стани:
- очікування (pending): початковий стан, не виконаний та не відхилений.
- виконано (fulfilled): операцію завершено успішно.
- відхилено (rejected): операцію завершено з помилкою.
- Для чого потрібен метод Promise.all?
Очікує виконання всіх промісів або відхилення будь-якого з них.
Повертає проміс, який виконається після виконання всіх промісів. У випадку, якщо будь-який з промісів буде відхилено, Promise.all також буде відхилено.
У нього є аналог Promise.allSetled, який виконується як тільки всі отримані проміси завершені (виконані або відхилені), що містить масив результатів виконання отриманих промісів.
- Для чого потрібен метод Promise.race?
Очікує виконання або відхилення будь-якого з отриманих промісів. Повертає проміс, який буде виконано або відхилено з результатом виконання першого виконаного або відхиленого промісу.
- Для чого потрібна async/await функція?
Ключове слово async робить створену функцію асинхронною. Функція async може містити вираз await, який призупиняє виконання функції async і чекає відповіді від переданого Promise, потім відновлює виконання функції async і повертає отримане значення.
- Як обробляти помилки в async/await функції?
1 - Для цього можна використовувати конструкцію try…catch()
2 - викликати метод .catch() після виклику функції.
- Що таке event loop?
Це механізм, який відповідає за виконання коду, збору та обробки подій та виконання підзадач із черги.
У концепції event loop є кілька блоків:
- call stack - відповідає за створення контексту виконання функції. Кожна функція, що викликається, потрапляє в call stack.
- heap - це велика не структурована область пам’яті, в якій зберігаються оголошені змінні, функції тощо.
- third party API - API, які надає оточення. Наприклад, метод fetch, який надається браузером.
- queue - список завдань, що підлягають обробці. Кожне завдання асоціюється з деякою функцією, яка буде викликана, щоб опрацювати це завдання.