Відповіді на запитання по JavaScript

Тут ти знайдеш відповіді на питання, які часто зустрічаються на співбесідах

До 2009 року, кожне нововведення в JS не торкалося старих можливостей. З виходом стандарту ECMAScript5 у JavaScript було внесено багато нового, але й стара функціональність була підправлена.

Для того, щоб браузери розуміли старий код, за замовчуванням ці нововведення не застосовуються.

Для активації в нашому коді всіх доданих в JS фіч починаючи з ES5 потрібно на початку скрипту поставити "use strict".

Важливо відзначити кілька особливостей використання строгого режиму:

  • перед "use strict" нічого не повинно бути (крім коментарів), це повинна бути перша строка коду
  • use strict не можна скасувати
  • якщо ви використовуєте класи та модулі, строгий режим включається автоматично

=== і !== є операторами жорсткого порівняння, тобто, якщо в операндів різні типи, результат буде false

== та != можна назвати операторами грубого порівняння. Якщо операнди мають різні типи, JavaScript спробує перетворити їх до єдиного і після цього порівняти.
Це видно на прикладах.

Для кращого розуміючи теми, вивчи перетворення типів в JS.

1 === "1" // false 1 !== "1" // true null === undefined // false false === 0 // false "0" == 0 // true 0 == "" // true "0" == "" // false false == 0 // true null == undefined // true [] == 0 // true

Async/await – це синтаксис для роботи з асинхронністю за допомогою промісів.

Ключове слово async робить функцію асинхронною, наприклад, такі функції слід використовувати для роботи з API та роботи з файлами. Функція з async повертає Promise.

Ключове слово await говорить про те, що наш код буде чекати поки виконається функція справа від await.

//async says that the function will be asynchronous async function getData(){ //waiting for fetch request to be done const response = await fetch(`https://some-api`); console.log("data received", response); return response.json(); } const data = getData().then((d) => { console.log(d) }) console.log("async function called", data); Result: "async function called" Promise "data received" Response

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

Прототипи – це механізм, за допомогою якого об'єкти JavaScript успадковують властивості один від одного. Це досить складна тема, щоб коротко її пояснити в обному параграфі, так що ось тобі хороша стаття з прикладами.

let та const сучасні варіанти оголошення змінних.

var застарілий варіант.

let - нормальна змінна значення якої можна змінювати.

const – константа. Значення цієї змінної буде незмінне, і спроба змінити його призведе до помилки. З const є одна тонкість, якщо ви створили константу об'єкта, ви можете змінювати його внутрішній стан, але ви не можете змінити цю константу, наприклад, на число чи рядок.

var – дуже схожа на let, тобто це звичайна змінна. Але є важлива відмінність, для var немає блокової області видимості. Наприклад, якщо ви оголосите змінну var всередині функції, ви не матимете доступу до цієї змінної. А якщо ви оголосите змінну var у блоці if або for ви матимете до неї доступ і поза цим блоком.

//var will not be available outside of the function function sayHi(){ var phrase = "Hi!"; console.log(phrase); //Hi! } sayHi(); console.log(phrase); //Error - phrase is not defined //var is available outside the if block if(true){ var test = true; } console.log(test); //true

this - це посилання на об'єкт властивості якого ми можемо використовувати всередині функції під час її виконання.

Примітивні типи даних

  • Число (number) - цей тип містить цілі та числа з плаваючою точкою, а також спеціальні значення Infinity, -Infiniti та NaN
  • BigInt - ціле число більше ніж 2^53-1. Ці числа вже не поміщаються у звичайний тип number
  • Рядок (string) - послідовність символів. Будь-які текстові дані в JS це рядки. Рядки записуються всередині лапок (' ' або " ") або шаблонним рядком зі зворотним апострофом (`)
  • Булевий тип (boolean) - може приймати тільки два логічні значення: true (істина) і false (брехня)
  • null - містить лише одне значення null, що означає "нічого", "порожньо" або "відсутня". Null використовують коли явно потрібно вказати на відсутність значення
  • undefined - так само як null, є окремим типом даних і позначає "значення не було присвоєно". Якщо змінна оголошена, але їй не присвоєно жодного значення, то її значенням буде undefined
  • Символ (symbol) - тип даних, значення якого створюються за допомогою виклику функції Symbol. Кожен створений символ є унікальним. Символи можуть використовуватися як імена властивостей в об'єктах.

Усі перелічені вище типи ставляться до примітивних, оскільки можуть містити лише одне значення, чи то рядок чи число. Окремо від них існує тип даних Об'єкт (Object), може зберігати у собі кілька примітивів чи інші об'єкти.

Map - це колекція ключ/значення, як і Object. Але основна відмінність у тому, що Map дозволяє використовувати ключі будь-якого типу.

Методи та властивості:

  • new Map([iterable]) - створює колекцію, можна вказати об'єкт, що перебирається (зазвичай масив) з пар [ключ,значення] для ініціалізації.
  • map.set(key, value) - записує з ключом key значення value.
  • map.get(key) - повертає значення по ключу або undefined, якщо ключ немає.
  • map.has(key) - повертає true, якщо ключ key є в колекції, інакше false.
  • map.delete(key) - видаляє елемент за ключом key.
  • map.clear() - очищає колекцію від всіх елементів.
  • map.size - повертає поточну кількість елементів.

Set - це особливий вид колекції: безліч значень (без ключів), де кожне значення може з'являтися лише один раз.

Методи та властивості:

  • new Set(iterable) – створює Set, і якщо як аргумент був наданий об'єкт, що ітерується (зазвичай це масив), то копіює його значення в новий Set.
  • set.add(value) – додає значення (якщо воно вже є, то нічого не робить), повертає той самий об'єкт set.
  • set.delete(value) – видаляє значення, повертає true, якщо value було в безлічі на момент виклику, інакше false.
  • set.has(value) – повертає true, якщо значення є у колекції, інакше false.
  • set.clear() - видаляє всі значення.
  • set.size - повертає кількість елементів у колекції.

WeakMap – схожа на Map, дозволяє використовувати як ключі тільки об'єкти, і автоматично видаляє їх разом із відповідними значеннями, як тільки вони ніде не використовуються, крім як як ключ цієї колекції

WeakSet – схожа на Set, зберігає лише об'єкти та видаляє їх, як тільки вони ніде не використовуються, окрім як у цій колекції.

Проміси - це об'єкти для роботи з асинхронністю. Усередині промісу працює асинхронна функція, яка змінює його стан.

За результатами своєї роботи проміс може бути або fulfilled (успішний), або rejected (з помилкою), дивись код прикладу.

Для обробки, у промісу є три методи:

  1. then - використовується для обробки даних, які повертає асинхронна функція при успішному завершенні
  2. catch - обробляє помилки, що виникли в промісі
  3. finally - викликається в будь-якому випадку, чи незалежно успішно відпрацював проміс
function getData(){ return new Promise(function (resolve, reject) { const result = tryGetData() //asynchronous operation if(result.ok){ resolve(result) //translate the promise into fulfilled and pass the result } else { reject(new Error(result)) } }) } getData() .then(function(res) { console.log("data received successfully", res) }) .catch(function(err) { console.error(err.message) })

Замикання це використання функції всередині іншої функції, коли внутрішня функція має доступ до змінних свого батька. Класичним прикладом замикань є лічильник (дивись прикладу). Зверніть увагу, що кожен новий виклик створює окрему область видимості.

function counter(){ let state = 0; function increase(){ state++; console.log(state) } function decrease(){ state--; console.log(state); } return {increase, decrease} } const ticktock1 = counter(); const ticktock2 = counter(); ticktock1.increase() //1 ticktock1.increase() //2 ticktock2.increase() //1 ticktock1.increase() //3 ticktock1.decrease() //2 ticktock2.increase() //2

Область видимості - це частина програми, в якій ми можемо звернутися до змінної, функції або об'єкта. Цією частиною може бути функція, блок чи вся програма загалом. Область видимості можна представити як коробку в яку вміщена та чи інша змінна.

const a = 48; console.log(a) //48 if(true){ const b = 54; console.log(a) //48 console.log(b) // 54 } function foo1(){ const c = 82; console.log(a) //48 console.log(c) //82 function foo2(){ const d = 11; console.log(a) //48 console.log(c) //82 console.log(d) //11 } foo2(); console.log(d) //ReferenceError: Can't find variable: d } foo1(); console.log(a) //48 console.log(b) //ReferenceError: Can't find variable: b console.log(c) //ReferenceError: Can't find variable: c console.log(d) //ReferenceError: Can't find variable: d

Це досить складне та об'ємне питання, яке потребує глибокого розуміння для роботи з іншою функціональністю JS.

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

Інші питання

Якщо у тебе є питання чи пропозиції, напиши мені: Telegram | LinkedIn
© 2023 All rights reserved