Skip to content

Latest commit

 

History

History
1417 lines (950 loc) · 46 KB

README.md

File metadata and controls

1417 lines (950 loc) · 46 KB

Список (просунутих) питань з JavaScript

Я публікую щодня завдання з JavaScript в моєму Instagram, які також додаю тут!

Від базового до просунутого: перевірте, наскільки добре ви знаєте JavaScript, трохи оновіть свої знання або підготуйтеся до інтерв'ю! 💪 🚀 Щотижня я доповнюю цей репозиторій новими питаннями.

Відповіді знаходяться в згорнутій секції нижче питань. Просто натисни на відповідь, щоб розгорнути. Успіхів! ❤️


1. Що буде в консолі?
function sayHi() {
  console.log(name);
  console.log(age);
  var name = "Lydia";
  let age = 21;
}

sayHi();
  • A: Lydia та undefined
  • B: Lydia та ReferenceError
  • C: ReferenceError та 21
  • D: undefined та ReferenceError
Відповідь

Відповідь: D

Всередині функції ми спершу визначаємо змінну name за допомогою ключового слова var. Це означає, що змінна буде знайдена (область пам'яті під змінну буде виділена під час створення) зі значенням undefined за замовчуванням, до тих пір поки виконання коду не дійде до рядка, де визначається змінна. Ми ще не визначили значення name, коли намагаємося вивести її в консоль, тому в консолі буде undefined.

Змінні, визначені за допомогою letconst), також знаходяться, але на відміну від var, не створюються. Доступ до них неможливий до тих пір, поки не виконається рядок їх визначення (ініціалізації). Це називається "тимчасова мертва зона". Коли ми намагаємося звернутися до змінних до того моменту як вони визначені, JavaScript видає ReferenceError.


2. Що буде в консолі?
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}
  • A: 0 1 2 та 0 1 2
  • B: 0 1 2 та 3 3 3
  • C: 3 3 3 та 0 1 2
Відповідь

Відповідь: C

Через черги подій в JavaScript, функція setTimeout викликається після того як цикл буде завершено. Так як змінна i в першому циклі була визначена за допомогою var, вона буде глобальною. У циклі ми кожен раз збільшуємо значення i на 1, використовуючи унарний оператор ++. До моменту виконання функції setTimeout значення i дорівнюватиме 3, як показано в першому прикладі.

У другому циклі змінна i визначена за допомогою let. Такі змінні (а також const) мають блокову область видимості (блок це що завгодно між {}). З кожною ітерацією i матиме нове значення, і кожне значення буде замкнуто у своїй області видимості всередині циклу.


3. Що буде в консолі?
const shape = {
  radius: 10,
  diameter() {
    return this.radius * 2;
  },
  perimeter: () => 2 * Math.PI * this.radius
};

shape.diameter();
shape.perimeter();
  • A: 20 та 62.83185307179586
  • B: 20 та NaN
  • C: 20 та 63
  • D: NaN та 63
Відповідь

Відповідь: B

Зауваж, що diameter це звичайна функція, в той час як perimeter це стрілкова функція.

У стрілкових функцій значення this вказує на навколишню область видимості, на відміну від звичайних функцій! Це означає, що при виклику perimeter значення this у цій функції вказує не на об'єкт shape, а на зовнішню область видимості (наприклад, window).

У цього об'єкта немає ключа radius, тому повертається undefined.


4. Що буде в консолі?
+true;
!"Lydia";
  • A: 1 та false
  • B: false та NaN
  • C: false та false
Відповідь

Відповідь: A

Унарний плюс призводить операнд до числа. true це 1, а false це 0.

Строка 'Lydia' це "справжнє" значення. Ми запитуємо "справжнє значення є помилковим"? Відповідь: false.


5. Що з цього не є коректним?
const bird = {
  size: "small"
};

const mouse = {
  name: "Mickey",
  small: true
};
  • A: mouse.bird.size не є коректно
  • B: mouse[bird.size] не є коректно
  • C: mouse[bird["size"]] не є коректно
  • D: Все варіант коректні
Відповідь

Відповідь: A

В JavaScript все ключі об'єкта є рядками (крім Symbol). І хоча ми не набираємо їх як рядки, вони завжди перетворюються до рядків під капотом.

JavaScript інтерпретує (або розпаковує) оператори. При використанні квадратних дужок JS зауважує [ і продовжує поки не зустріне ]. Тільки після цього він вирахує то, що знаходиться всередині дужок.

mouse[bird.size]: Спершу визначається bird.size, що дорівнює "small". mouse["small"] повертає true.

Але із записом через крапку так не відбувається. У mouse немає ключа bird. Таким чином, mouse.bird дорівнює undefined. Потім ми запитуємо ключ size, використовуючи крапкову нотацію: mouse.bird.size. Так як mouse.bird це undefined, ми запитуємо undefined.size. Це не є дійсним, тому ми отримуємо помилку типу: Can not read property "size" of undefined.


6. Що буде в консолі?
let c = { greeting: "Hey!" };
let d;

d = c;
c.greeting = "Hello";
console.log(d.greeting);
  • A: Hello
  • B: Hey
  • C: undefined
  • D: ReferenceError
  • E: TypeError
Відповідь

Відповідь: A

В JavaScript всі об'єкти є посилальними типами даних.

Спершу змінна c вказує на об'єкт. Потім ми вказуємо змінної d посилатися на той самий об'єкт, що і c.

Коли ти змінюєш один об'єкт, то змінюються значення всіх посилань, що вказують на цей об'єкт.


7. Що буде в консолі?
let a = 3;
let b = new Number(3);
let c = 3;

console.log(a == b);
console.log(a === b);
console.log(b === c);
  • A: true false true
  • B: false false true
  • C: true false false
  • D: false true true
Відповідь

Відповідь: C

new Number() це вбудований конструктор функції. І хоча він виглядає як число, це не справжнє число: у нього є ряд додаткових фіч і це об'єкт.

Оператор == призводить типи даних до якогось одного і перевіряє рівність значень. Обидва значення рівні 3, тому повертається true.

При використанні оператора === значення і тип повинні бути однаковими. Але в нашому випадку це не так: new Number() це не число, це об'єкт. Тому обидва повертають false.


8. Яким буде результат?
class Chameleon {
  static colorChange(newColor) {
    this.newColor = newColor;
    return this.newColor;
  }

  constructor({ newColor = "green" } = {}) {
    this.newColor = newColor;
  }
}

const freddie = new Chameleon({ newColor: "purple" });
freddie.colorChange("orange");
  • A: orange
  • B: purple
  • C: green
  • D: TypeError
Відповідь

Відповідь: D

Функція colorChange є статичною. Статичні методи не мають доступу до екземплярів класу. Так як freddie це екземпляр, то статичний метод там не доступний. Тому результатом є помилка TypeError.


9. Що буде в консолі?
let greeting;
greetign = {}; // Typo!
console.log(greetign);
  • A: {}
  • B: ReferenceError: greetign is not defined
  • C: undefined
Відповідь

Відповідь: A

В консолі виведеться об'єкт, тому що ми щойно створили порожній об'єкт в глобальному об'єкті! Коли ми замість greeting написали greetign, інтерпретатор JS насправді виконав global.greetign = {} (або window.greetign = {} в браузері).

Потрібно використовувати "use strict", щоб уникнути такої поведінки. Цей запис допоможе бути впевненим в тому, що змінна була визначена перед тим як їй присвоїли значення.


10. Що станеться?
function bark() {
  console.log("Woof!");
}

bark.animal = "dog";
  • A: Нічого, все ок.
  • B: SyntaxError. Не можна додавати властивості функцій таким способом.
  • C: undefined
  • D: ReferenceError
Відповідь

Відповідь: A

В JavaScript це можливо, тому що функції це об'єкти! (Все є об'єктами крім примітивів).

Функція - це спеціальний тип об'єкта, який можна викликати. Крім того, функція - це об'єкт з властивостями. Властивість такого об'єкта не можна викликати, так як воно не є функцією.


11. Що буде в консолі?
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

const member = new Person("Lydia", "Hallie");
Person.getFullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

console.log(member.getFullName());
  • A: TypeError
  • B: SyntaxError
  • C: Lydia Hallie
  • D: undefined undefined
Відповідь

Відповідь: A

Не можна додавати властивості конструктору, як звичайному об'єкту. Якщо потрібно додати фічу до всіх об'єктів, то необхідно використовувати прототипи. В даному випадку,

Person.prototype.getFullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

зробить метод member.getFullName() чинним. У чому тут перевага? Припустимо, що ми додали цей метод до конструктора. Можливо, не кожному екземпляру Person потрібен цей метод. Це призведе до великих втрат пам'яті, тому що всі екземпляри будуть мати цю властивість. Навпаки, якщо ми додамо цей метод тільки до прототипу, у нас буде тільки одне місце в пам'яті, до якого зможуть звертатися всі екземпляри!


12. Що буде в консолі?
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

const lydia = new Person("Lydia", "Hallie");
const sarah = Person("Sarah", "Smith");

console.log(lydia);
console.log(sarah);
  • A: Person {firstName: "Lydia", lastName: "Hallie"} та undefined
  • B: Person {firstName: "Lydia", lastName: "Hallie"} та Person {firstName: "Sarah", lastName: "Smith"}
  • C: Person {firstName: "Lydia", lastName: "Hallie"} та {}
  • D:Person {firstName: "Lydia", lastName: "Hallie"} та ReferenceError
Відповідь

Відповідь: A

Для sarah ми не використали ключове слово new. Використання new призводить до створення нового об'єкта. Але без new він вказує на глобальний об'єкт!

Ми вказали, що this.firstName дорівнює "Sarah" і this.lastName дорівнює "Smith". Насправді ми визначили global.firstName = 'Sarah' і global.lastName = 'Smith'. sarah залишилася undefined.


13. Назвіть три фази поширення подій
  • A: Мета (Target) > Захоплення (Capturing) > Спливання (Bubbling)
  • B: Спливання (Bubbling) > Мета (Target) > Захоплення (Capturing)
  • C: Мета (Target) > Спливання (Bubbling) > Захоплення (Capturing)
  • D: Захоплення (Capturing) > Мета (Target) > Спливання (Bubbling)
Відповідь

Відповідь: D

Під час фази захоплення подія поширюється від батьківського елемента до елемента мети. Після досягнення мети починається фаза спливання.


14. Всі об'єкти мають прототипи?
  • A: Так
  • B: Ні
Відповідь

Відповідь: B

Всі об'єкти мають прототипи, крім базового об'єкта. Базовий об'єкт має доступ до деяких методів і властивостей, таких як .toString. Саме тому ми можемо використовувати вбудовані методи JavaScript! Всі ці методи доступні в прототипі. Якщо JavaScript не може знайти метод безпосередньо у об'єкту, він продовжує пошук по ланцюжку прототипів поки не знайде.


15. Результат коду?
function sum(a, b) {
  return a + b;
}

sum(1, "2");
  • A: NaN
  • B: TypeError
  • C: "12"
  • D: 3
Відповідь

Відповідь: C

JavaScript це динамічно типізована мова: ми не визначаємо тип змінних. Змінні можуть автоматично бути перетворені з одного типу в інший без нашої участі, що називається неявним приведенням типів. Приведення це перетворення з одного типу в інший.

У цьому прикладі, JavaScript конвертувати число 1 в рядок, щоб операція всередині функції мала сенс і повернула значення. Під час складання числа (1) і рядки ('2') число перетворюється до рядка. Ми можемо додавати рядки ось так: "Hello" + "World". Таким чином, "1" + "2" повертає "12".


16. Що буде в консолі?
let number = 0;
console.log(number++);
console.log(++number);
console.log(number);
  • A: 1 1 2
  • B: 1 2 2
  • C: 0 2 2
  • D: 0 1 2
Відповідь

Відповідь: C

Постфіксний унарний оператор ++:

  1. Повертає значення (0)
  2. Інкрементує значення (тепер число дорівнює 1)

Префіксний унарний оператор ++:

  1. Інкрементує значення (тепер число дорівнює 2)
  2. Повертає значення (2)

Результат: 0 2 2.


17. Що буде в консолі?
function getPersonInfo(one, two, three) {
  console.log(one);
  console.log(two);
  console.log(three);
}

const person = "Lydia";
const age = 21;

getPersonInfo`${person} is ${age} years old`;
  • A: "Lydia" 21 ["", " is ", " years old"]
  • B: ["", " is ", " years old"] "Lydia" 21
  • C: "Lydia" ["", " is ", " years old"] 21
Відповідь

Відповідь: B

При використанні тегованих шаблонних літералів першим аргументом завжди буде масив строкових значень. Решта аргументів будуть значення мати переданих виразів!


18. Що буде в консолі?
function checkAge(data) {
  if (data === { age: 18 }) {
    console.log("You are an adult!");
  } else if (data == { age: 18 }) {
    console.log("You are still an adult.");
  } else {
    console.log(`Hmm.. You don't have an age I guess`);
  }
}

checkAge({ age: 18 });
  • A: You are an adult!
  • B: You are still an adult.
  • C: Hmm.. You don't have an age I guess
Відповідь

Відповідь: C

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

Порівнювані об'єкти в нашому прикладі не такі: об'єкт, переданий як параметр, вказує на іншу область пам'яті, ніж об'єкти, що використовуються в порівнянні.

Тому {age: 18} === {age: 18} і {age: 18} == {age: 18} повертають false.


19. Що буде в консолі?
function getAge(...args) {
  console.log(typeof args);
}

getAge(21);
  • A: "number"
  • B: "array"
  • C: "object"
  • D: "NaN"
Відповідь

Відповідь: C

Оператор поширення (... args) повертає масив з аргументами. Масив це об'єкт, тому typeof args повертає "object".


20. Що буде в консолі?
function getAge() {
  "use strict";
  age = 21;
  console.log(age);
}

getAge();
  • A: 21
  • B: undefined
  • C: ReferenceError
  • D: TypeError
Відповідь

Відповідь: C

Використовуючи "use strict", можна бути впевненим, що ми помилково не оголосимо глобальні змінні. Ми раніше ніде не оголошували змінну age, тому з використанням "use strict" виникне ReferenceError. Без використання "use strict" помилки не виникне, а змінна age додасться в глобальний об'єкт.


21. Чому дорівнюватиме sum?
const sum = eval("10*10+5");
  • A: 105
  • B: "105"
  • C: TypeError
  • D: "10*10+5"
Відповідь

Відповідь: A

eval виконує код, переданий у вигляді рядка. Якщо це рядок (як в такому випадку), то обчислюється вираз. Вираз 10 * 10 + 5 поверне число 105.


22. Як довго буде доступний cool_secret?
sessionStorage.setItem("cool_secret", 123);
  • A: Завжди, дані не загубляться.
  • B: Поки користувач не закриває вкладку.
  • C: Поки користувач не закриє браузер, а не тільки вкладку.
  • D: Поки користувач не вимикає комп'ютер.
Відповідь

Відповідь: B

Дані, збережені в sessionStorage очищаються після закриття вкладки.

При використанні localStorage дані зберігаються назавжди. Очистити їх можна, наприклад, використовуючи localStorage.clear().


23. Що буде в консолі?
var num = 8;
var num = 10;

console.log(num);
  • A: 8
  • B: 10
  • C: SyntaxError
  • D: ReferenceError
Відповідь

Відповідь: B

За допомогою ключового слова var, можна визначати скільки завгодно змінних з одним і тим же ім'ям. Змінна зберігатиме останнє присвоєне значення.

Ви не можете зробити це з let або const, оскільки вони блочні.


24. Що буде в консолі?
const obj = { 1: "a", 2: "b", 3: "c" };
const set = new Set([1, 2, 3, 4, 5]);

obj.hasOwnProperty("1");
obj.hasOwnProperty(1);
set.has("1");
set.has(1);
  • A: false true false true
  • B: false true true true
  • C: true true false true
  • D: true true true true
Відповідь

Відповідь: C

Всі ключі об'єктів (крім Symbols) є рядками, навіть якщо задано не в вигляді рядків. Тому obj.hasOwnProperty('1') так само повертає true.

Але це не працює для set. Значення "1" немає в set: set.has ('1'), тому повертається false. Але set.has(1) поверне true.


25. Що буде в консолі?
const obj = { a: "one", b: "two", a: "three" };
console.log(obj);
  • A: { a: "one", b: "two" }
  • B: { b: "two", a: "three" }
  • C: { a: "three", b: "two" }
  • D: SyntaxError
Відповідь

Відповідь: C

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


26. Глобальний контекст виконання створює дві речі: глобальний об'єкт і this
  • A: Так
  • B: Ні
  • C: В залежності від ситуації
Відповідь

Відповідь: A

Базовий контекст виконання це глобальний контекст виконання: це те, що є де завгодно у твоєму коді.


27. Що буде в консолі?
for (let i = 1; i < 5; i++) {
  if (i === 3) continue;
  console.log(i);
}
  • A: 1 2
  • B: 1 2 3
  • C: 1 2 4
  • D: 1 3 4
Відповідь

Відповідь: C

Оператор continue пропускає ітерацію, якщо умова повертає true.


28. Яким буде результат?
String.prototype.giveLydiaPizza = () => {
  return "Just give Lydia pizza already!";
};

const name = "Lydia";

console.log(name.giveLydiaPizza())
  • A: "Just give Lydia pizza already!"
  • B: TypeError: not a function
  • C: SyntaxError
  • D: undefined
Відповідь

Відповідь: A

String це вбудований конструктор, до якого можна додавати властивості. Я додала метод до його прототипу. Рядки-примітиви автоматично конвертуються до рядків-об'єктів. Тому всі рядки (строкові об'єкти) мають доступ до цього методу!


29. Що буде в консолі?
const a = {};
const b = { key: "b" };
const c = { key: "c" };

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

console.log(a[b]);
  • A: 123
  • B: 456
  • C: undefined
  • D: ReferenceError
Відповідь

Відповідь: B

Ключі об'єкта автоматично конвертуються в рядки. Ми збираємося додати об'єкт в якості ключа до об'єкта a зі значенням 123.

Проте, коли ми наводимо об'єкт до рядка, він стає "[object Object]". Таким чином, ми говоримо, що a["object Object"] = 123. Потім ми робимо те ж саме. c це інший об'єкт, який ми неявно наводимо до рядка. Тому a["object Object"] = 456.

Потім, коли ми виводимо a[b], ми маємо на увазі a["object Object"]. Ми тільки що встановили туди значення 456, тому в результаті отримуємо 456.


30. Яким буде результат?
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"));
const baz = () => console.log("Third");

bar();
foo();
baz();
  • A: First Second Third
  • B: First Third Second
  • C: Second First Third
  • D: Second Third First
Відповідь

Відповідь: B

Ми викликаємо функцію setTimeout першою. Тим не менш, вона виводиться в консоль останньою.

Це відбувається через те, що в браузерах у нас є не тільки рантайм движок, але і WebAPI. WebAPI надає нам функцію setTimeout і багато інших можливостей. Наприклад, DOM.

Після того як коллбек відправлений в WebAPI, функція setTimeout (але не коллбек!) виймається з стека.

Тепер викликається foo, і "First" виводиться в консоль.

foo дістається з стека, і викликається baz. "Third" виводиться в консоль.

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

Тут на сцену виходить цикл подій (event loop). Event loop перевіряє стек і черга завдань. Якщо стек порожній, то він бере перший елемент з черги і відправляє його в стек.

Викликається bar, в консоль виводиться "Second" і ця функція дістається з стека.


31. Що буде в event.target після кліка на кнопку?
<div onclick="console.log('first div')">
  <div onclick="console.log('second div')">
    <button onclick="console.log('button')">
      Click!
    </button>
  </div>
</div>
  • A: Зовнішній div
  • B: Внутрішній div
  • C: button
  • D: Масив з усіма вкладеними елементами
Відповідь

Відповідь: C

Метою події є найглибший вкладений елемент. Зупинити поширення подій можна за допомогою event.stopPropagation


32. Що буде в консолі після кліка по параграфу?
<div onclick="console.log('div')">
  <p onclick="console.log('p')">
    Click here!
  </p>
</div>
  • A: p div
  • B: div p
  • C: p
  • D: div
Відповідь

Відповідь: A

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


33. Що буде в консолі?
const person = { name: "Lydia" };

function sayHi(age) {
  console.log(`${this.name} is ${age}`);
}

sayHi.call(person, 21);
sayHi.bind(person, 21);
  • A: undefined is 21 Lydia is 21
  • B: function function
  • C: Lydia is 21 Lydia is 21
  • D: Lydia is 21 function
Відповідь

Відповідь: D

В обох випадках ми передаємо об'єкт, на який буде вказувати this. Але .call виконується відразу ж!

.bind повертає копію функції, але з прив'язаним контекстом. Вона не виконується негайно.


34. Яким буде результат?
function sayHi() {
  return (() => 0)();
}

typeof sayHi();
  • A: "object"
  • B: "number"
  • C: "function"
  • D: "undefined"
Відповідь

Відповідь: B

Функція sayHi повертає значення, що повертається з негайно викликаного функціонального виразу (IIFE). Результатом є 0 типу "number".

Для інформації: в JS 7 вбудованих типів: null, undefined, boolean, number, string, object, symbol, та bigint. "Function" не є окремим типом, тому що функції є об'єктами типу "object".


35. Які з цих значень є "помилковими"?
0;
new Number(0);
("");
(" ");
new Boolean(false);
undefined;
  • A: 0, '', undefined
  • B: 0, new Number(0), '', new Boolean(false), undefined
  • C: 0, '', new Boolean(false), undefined
  • D: Всі значення.
Відповідь

Відповідь: A

Є тільки шість "помилкових" значень:

  • undefined
  • null
  • NaN
  • 0
  • '' (порожній рядок)
  • false

Конструктори функцій, такі як new Number та new Boolean є "істинними".


36. Що буде в консолі?
console.log(typeof typeof 1);
  • A: "number"
  • B: "string"
  • C: "object"
  • D: "undefined"
Відповідь

Відповідь: B

typeof 1 повертає "number". typeof "number" повертає "string"


37. Що буде в консолі?
const numbers = [1, 2, 3];
numbers[10] = 11;
console.log(numbers);
  • A: [1, 2, 3, 7 x null, 11]
  • B: [1, 2, 3, 11]
  • C: [1, 2, 3, 7 x empty, 11]
  • D: SyntaxError
Відповідь

Відповідь: C

Коли в масив додається значення, яке виходить за межі довжини масиву, JavaScript створює так звані "порожні клітинки". Насправді вони мають значення undefined, але в консолі виводяться так:

[1, 2, 3, 7 x empty, 11]

в залежності від місця використання (може відрізнятися для браузерів, Node, і т.д.).


38. Що буде в консолі?
(() => {
  let x, y;
  try {
    throw new Error();
  } catch (x) {
    (x = 1), (y = 2);
    console.log(x);
  }
  console.log(x);
  console.log(y);
})();
  • A: 1 undefined 2
  • B: undefined undefined undefined
  • C: 1 1 2
  • D: 1 undefined undefined
Відповідь

Відповідь: A

Блок catch отримує аргумент x. Це не той же x, який визначено в якості змінної перед рядком try.

Потім ми присвоюємо даному аргументу значення 1 та встановлюємо значення для змінної y. Потім виводимо в консоль значення аргументу x, що дорівнює 1.

За межами блоку catch змінна x все ще undefined, а y дорівнює 2. Коли ми викликаємо console.log(x) за межами блоку catch, цей виклик повертає undefined, а y повертає 2.


39. Все в JavaScript це...
  • A: примітив або об'єкт
  • B: функція або об'єкт
  • C: питання з підступом! тільки об'єкти
  • D: число або об'єкт
Відповідь

Відповідь: A

В JavaScript є тільки примітиви й об'єкти.

Типи примітивів: boolean, null, undefined, bigint, number, string, та symbol.

Відмінністю примітиву від об'єкта є те, що примітиви не мають властивостей або методів. Проте, 'foo'.toUpperCase() перетворюється в 'FOO' та не викликає TypeError. Це відбувається тому, що при спробі отримання властивості або методу у примітиву (наприклад, рядки), JavaScript неявно оберне примітив об'єктом, використовуючи один з класів-обгорток (наприклад, String), а потім відразу ж знищить обгортку після обчислення виразу. Всі примітиви крім null та undefined поводяться таким чином.


40. Що буде в консолі?
[[0, 1], [2, 3]].reduce(
  (acc, cur) => {
    return acc.concat(cur);
  },
  [1, 2]
);
  • A: [0, 1, 2, 3, 1, 2]
  • B: [6, 1, 2]
  • C: [1, 2, 0, 1, 2, 3]
  • D: [1, 2, 6]
Відповідь

Відповідь: C

[1, 2] - початкове значення, з яким ініціалізується змінна acc. Після першого проходу acc дорівнюватиме [1,2], а cur буде [0,1]. Після конкатенації результат буде [1, 2, 0, 1].

Потім acc дорівнює [1, 2, 0, 1], а cur [2, 3]. Після злиття отримаємо [1, 2, 0, 1, 2, 3].


41. Що буде в консолі?
!!null;
!!"";
!!1;
  • A: false true false
  • B: false false true
  • C: false true true
  • D: true true false
Відповідь

Відповідь: B

null "НЕправдивий". !null повертає true. !true повертає false.

"" "НЕправдивий". !"" повертає true. !true повертає false.

1 "правдивий". !1 повертає false. !false повертає true.


42. Що повертає метод setInterval?
setInterval(() => console.log("Hi"), 1000);
  • A: унікальний id
  • B: вказану кількість мілісекунд
  • C: передану функцію
  • D: undefined
Відповідь

Відповідь: A

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


43. Що повернеться?
[..."Lydia"];
  • A: ["L", "y", "d", "i", "a"]
  • B: ["Lydia"]
  • C: [[], "Lydia"]
  • D: [["L", "y", "d", "i", "a"]]
Відповідь

Відповідь: A

Рядок є ітерабельною сутністю. Оператор поширення перетворює кожен символ в окремий елемент.


44. Що буде в консолі?
function* generator(i) {
  yield i;
  yield i * 2;
}

const gen = generator(10);

console.log(gen.next().value);
console.log(gen.next().value);
  • A: [0, 10], [10, 20]
  • B: 20, 20
  • C: 10, 20
  • D: 0, 10 and 10, 20
Answer

Відповідь: C

Звичайні функції не можна зупинити "на півдорозі" після виклику. Однак функція-генератор може зупинитися "на півдорозі", а потім продовжити з того місця, де вона зупинилась. Кожного разу, коли функція-генератор зустрічає ключове слово yield, функція видає значення, що вказане після нього. Зауважте, що функція-генератор в цьому випадку не повертає (return) значення, вона дає (yields) значення.

Спочатку ми ініціалізуємо функцію-генератор з i рівним 10. Ми викликаємо функцію-генератор за допомогою методу next(). Коли ми вперше викликаємо функцію генератора, i дорівнює 10. Перше ключове слово yield: воно дає значення i. Генератор тепер "призупинено", і 10 записується у консоль.

Потім ми знову викликаємо функцію за допомогою методу next(). Виконання коду продовжується там, де зупинилося раніше, все ще з i що дорівнює 10. Тепер функція зустрічає наступне ключове слово yield і дає i * 2. i дорівнює 10, тож віддається 10 * 2, що дорівнює 20. У результаті: 10, 20.


45. Що повернеться?
const firstPromise = new Promise((res, rej) => {
  setTimeout(res, 500, 'one');
});

const secondPromise = new Promise((res, rej) => {
  setTimeout(res, 100, 'two');
});

Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
  • A: "one"
  • B: "two"
  • C: "two" "one"
  • D: "one" "two"
Answer

Відповідь: B

Коли ми передаємо кілька промісів методу Promise.race, він вирішує/відхиляє перший проміс, яки вирішився/відхилився. Методу setTimeout ми передаємо таймер: 500 мс для першого промісу (firstPromise) та 100 мс для другого промісу (secondPromise). Це означає, що secondPromise вирішиться першим зі значенням 'two'. res тепер містить значення 'two', яке буде зображено у консолі.


46. Що буде на виході?
let person = { name: 'Lydia' };
const members = [person];
person = null;

console.log(members);
  • A: null
  • B: [null]
  • C: [{}]
  • D: [{ name: "Lydia" }]
Answer

Відповідь: D

Спочатку ми оголошуємо змінну person що містить об'єкта, який має властивість name.

Потім ми оголошуємо змінну members. Ми встановлюємо перший елемент масиву рівним значенню змінної person. Об'єкти взаємодіють за допомогою посилання, коли їх встановлюють рівними один одному. Коли ви призначаєте посилання з однієї змінної на іншу, ви робите копію цього посилання. (зверніть увагу, що вони не мають однакового посилання!)

Далі ми встановлюємо змінну person рівною null.

Ми лише змінюємо значення змінної person, а не перший елемент у масиві, оскільки цей елемент має інше (скопійоване) посилання на об’єкт.Перший елемент у members все ще містить своє посилання на вихідний об’єкт. Коли ми виводимо у консоль масив members, перший елемент усе ще містить значення об'єкта, який і показується у консолі.