Повернутися до всіх запитань

Яка різниця між null i undefined в JavaScript?

JuniorJavaScript
Зустрічали на інтервʼю:3 користувачів

Різниця між null i undefined - це класичне запитання на позицію junior-розробника. По своїй суті вони схожі і означають, що значення немає , але якщо копнути трошки глибше, різниця між ними стає очевидною. Отже, розберемо їх по черзі:

undefined

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

null

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

Наприклад, в базі даних не знайдено продукту за ID, і ви явно повертаєте null, тим самим даєте зрозуміти, що ви шукали і нічого не знайшли, тому в якості значення підставили null.

function findProductById(id) {
const products = [{ id: 1, name: "Phone" }]; // емулюємо базу даних

const product = products.find(p => p.id === id);

return product || null;
}

Зустрічав на інтервʼю?

Повʼязані питання

JuniorMiddleJavaScript

Як склонувати обʼєкт в JS?

Це бородате питання, яке досі задають на інтервʼю - зазвичай в компаніях, де люди явно засиділися і пропустили безліч оновлень в JS. В цілому є три найпоширеніші способи склонувати обʼєкт в JavaScript.

Spread оператор

Це найпростіший і найелегантніший спосіб. Єдиний нюанс в тому, що spread виконує shallow (поверхневе) клонування. Це означає, що всі вкладені обʼєкти не будуть склоновані і будуть посилатися на оригінальний обʼєкт.

const user = {
id: 1,
email: "test@test.com",
notifications: {
email: true
},
externalId: BigInt(232323345555),
};

const userClone = { ...user };

// Якщо ми змінимо значення поля user.notifications.email,
// то зміниться і userClone.notifications.email
// так як userClone.notifications не був склонований
// і фактично це просто посилання на user.notifications

user.notifications.email = false;

console.log(userClone.notifications.email); // false

JSON.stringify → JSON.parse

Старий дідівський метод, який робить deep clone (глибоке клонування) обʼєкта. Це означає, що всі вкладені обʼєкти будуть склоновані. В цілому цей спосіб робочий, але має одну проблему - він працює тільки з простими типами даних.

Якщо обʼєкт має поля з Map/Set, undefined, Infinity, BigInt і т.д., ми або отримаємо помилку, або поля будуть загублені чи конвертовані в рядок. Тому використовувати такий спосіб в реальному проєкті не найкраща ідея, і краще використовувати third party або спосіб, який я опишу далі.

const user = {
id: 1,
email: "test@test.com",
notifications: {
email: true
},
externalId: BigInt(232323345555),
};

// Так як externalId, це BigInt ми отримаємо помилку і клонування не відбудеться
const userClone = JSON.parse(JSON.stringify(user));

structuredClone

Це відносно новий метод в JS, який дозволяє робити глибоке клонування, в тому числі складних типів, з якими не справляється попередній метод. Він гарно розписаний в MDN, тому для детального розбору рекомендую прочитати документацію.

const user = {
id: 1,
email: "test@test.com",
notifications: {
email: true
},
externalId: BigInt(232323345555),
};

// Клонування буде успі
const user2 = structuredClone(user);


JavaScriptJunior

Яка різниця між let i var?

Це питання задають не часто, але воно все ще актуальне тому варто розуміти основні відмінності:

Область видимості

var має функціональну область видимості (function scope) тому якщо ми оголошуємо змінну var в блоці {}, вона все одно буде глобальна в рамках функції де була оголошена або в рамках глобального обʼєкту.

if (true) {
var a = 10;
let b = 20;
}

console.log(a); // 10
console.log(b); // undefined або помилка, якщо використовується strict mode

function fn() {
var c = 30;
}

console.log(c) // тут буде undefined, так як функція інкапсулює змінну c

Hoisting

В цілому, як var так і let піднімаються на початок області видимості, але є суттєва різниця при спробі доступу до них.

var піднімається і присвоюється значення undefined, яке ми отримуємо при доступі let піднімається, але при спробі доступу, отримаємо помилку.

console.log(x); // undefined
var x = 5;

console.log(y); // ReferenceError
let y = 10;

Повторне оголошення

var можна оголосити повторно в межах однієї області.

let не можна повторно оголосити в межах одного блоку, бо отримаємо помилку.

JuniorJavaScript

Які типи даних є в JavaScript?

Це питання часто викликає ступор навіть у сіньйорів, хоча насправді воно дуже просте.

Коли його чуєте, не потрібно вигадувати каруселі на кшталт: є масиви, об’єкти, функції… - бо з точки зору типів даних у JavaScript усе це належить до одного непримітивного типу - object.

Непримітивний тип: object

До object належить майже все “складне”:

  1. { a: 1 } - об’єкт
  2. [1, 2, 3] - масив (але тип все одно object)
  3. new Date() - дата (також object)
  4. function () {} - функція (технічно це об’єкт, але typeof для неї повертає function)

Примітивні типи (їх 7)

Окрім object, у JavaScript є 7 примітивних типів - вони не є об’єктами і не мають методів/властивостей як контейнери (хоча JS інколи обгортає їх у wrapper-об’єкти під капотом).

  1. string - рядки: hello
  2. number - числа: 42, 3.14, NaN, Infinity
  3. boolean - логічний тип: true / false
  4. null - порожнє значення (явно задана відсутність)
  5. undefined - значення не задане
  6. symbol - унікальні ідентифікатори: Symbol(id)
  7. bigint - великі цілі числа: 123n

Разом: 7 примітивів + 1 непримітивний тип object. Про різницю null та undefined ви можете почитати https://devs-hive.tech/interview-qa/null-vs-undefined-js.

Коментарі (0)

Увійдіть, щоб залишити коментар

Поки що немає коментарів. Будьте першим!