Skip to content
Open
Prev Previous commit
Next Next commit
add uk 126-135
  • Loading branch information
subqq committed Mar 14, 2024
commit 8e268bb5f88f95dc989f68579cc37f12eabf9b82
377 changes: 377 additions & 0 deletions uk-UA/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4067,3 +4067,380 @@ myFunc(1, 2, 3);

</p>
</details>

---

###### 126. Що буде на виході?

```javascript
function getFine(speed, amount) {
const formattedSpeed = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'mile-per-hour'
}).format(speed);

const formattedAmount = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(amount);

return `The driver drove ${formattedSpeed} and has to pay ${formattedAmount}`;
}

console.log(getFine(130, 300))
```

- A: The driver drove 130 and has to pay 300
- B: The driver drove 130 mph and has to pay \$300.00
- C: The driver drove undefined and has to pay undefined
- D: The driver drove 130.00 and has to pay 300.00

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: B

За допомогою методу `Intl.NumberFormat` ми можемо форматувати числові значення до будь-якої локалі. Ми форматуємо числове значення `130` до локалі `en-US` як `unit` в `mile-per-hour`, що призводить до `130 mph`. Числове значення `300` для локалі `en-US` як `currency` в `USD` призводить до `$300.00`.

</p>
</details>

---

###### 127. Що буде на виході?

```javascript
const spookyItems = ['👻', '🎃', '🕸'];
({ item: spookyItems[3] } = { item: '💀' });

console.log(spookyItems);
```

- A: `["👻", "🎃", "🕸"]`
- B: `["👻", "🎃", "🕸", "💀"]`
- C: `["👻", "🎃", "🕸", { item: "💀" }]`
- D: `["👻", "🎃", "🕸", "[object Object]"]`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: B

Деструктуруючи об’єкти, ми можемо розпаковувати значення з правого об’єкта та призначати це розпаковане значення значенню властивості з таким самим іменем у лівому об’єкті. У цьому випадку ми присвоюємо значення "💀" для `spookyItems[3]`. Це означає, що ми змінюємо масив `spookyItems`, ми додаємо до нього "💀". Коли ми логуємо `spookyItems`, дістаємо `["👻", "🎃", "🕸", "💀"]`.

</p>
</details>

---

###### 128. Що буде на виході?

```javascript
const name = 'Lydia Hallie';
const age = 21;

console.log(Number.isNaN(name));
console.log(Number.isNaN(age));

console.log(isNaN(name));
console.log(isNaN(age));
```

- A: `true` `false` `true` `false`
- B: `true` `false` `false` `false`
- C: `false` `false` `true` `false`
- D: `false` `true` `false` `true`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: C

За допомогою методу `Number.isNaN` ми можемо перевірити, чи значення, яке ми передаємо, є _числовим значенням_ і дорівнює `NaN`. `name` не є числовим значенням, тому `Number.isNaN(name)` повертає `false`. `age` — це числове значення, але не дорівнює `NaN`, тому `Number.isNaN(age)` повертає `false`.

За допомогою методу `isNaN` ми можемо перевірити, чи значення, яке ми передаємо, не є числом. `name` не є числом, тому `isNaN(name)` повертає `true`. `age` є числом, тому `isNaN(age)` повертає `false`.

</p>
</details>

---

###### 129. Що буде на виході?

```javascript
const randomValue = 21;

function getInfo() {
console.log(typeof randomValue);
const randomValue = 'Lydia Hallie';
}

getInfo();
```

- A: `"number"`
- B: `"string"`
- C: `undefined`
- D: `ReferenceError`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: D

Змінні, оголошені за допомогою ключового слова `const` не можуть використовуватись до їх ініціалізації: це називається _тимчасова мертва зона_. У функції `getInfo` змінна `randomValue` знаходиться у області видимості `getInfo`. У рядку, де ми хочемо залогувати значення `typeof randomValue`, змінна `randomValue` ще не ініціалізована: викидається `ReferenceError`! Рушій JavaScript не шукав у ланцюжку області видимості, оскільки ми оголосили змінну `randomValue` у функції `getInfo`.

</p>
</details>

---

###### 130. Що буде на виході?

```javascript
const myPromise = Promise.resolve('Woah some cool data');

(async () => {
try {
console.log(await myPromise);
} catch {
throw new Error(`Oops didn't work`);
} finally {
console.log('Oh finally!');
}
})();
```

- A: `Woah some cool data`
- B: `Oh finally!`
- C: `Woah some cool data` `Oh finally!`
- D: `Oops didn't work` `Oh finally!`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: C

У блоці `try` ми логуємо await значення змінної `myPromise`: `"Woah some cool data"`. Оскільки в блоці `try` не виникло помилок, код у блоці `catch` не виконується. Код у блоці `finally` _завжди_ виконується, `"Oh finally!"` логується у консоль.

</p>
</details>

---

###### 131. Що буде на виході?

```javascript
const emojis = ['🥑', ['✨', '✨', ['🍕', '🍕']]];

console.log(emojis.flat(1));
```

- A: `['🥑', ['✨', '✨', ['🍕', '🍕']]]`
- B: `['🥑', '✨', '✨', ['🍕', '🍕']]`
- C: `['🥑', ['✨', '✨', '🍕', '🍕']]`
- D: `['🥑', '✨', '✨', '🍕', '🍕']`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: B

За допомогою методу `flat` ми можемо створити новий плоский масив з багатовимірного. Глибина плоского масиву залежить від значення, яке ми передаємо. У цьому випадку ми передали значення `1` (чого ми могли б не робити, це значення за замовчуванням), що означає, що лише масиви на першій глибині будуть об’єднані. `['🥑']` та `['✨', '✨', ['🍕', '🍕']]` в цьому випадку. Об’єднання цих двох масивів призводить до `['🥑', '✨', '✨', ['🍕', '🍕']]`.

</p>
</details>

---

###### 132. Що буде на виході?

```javascript
class Counter {
constructor() {
this.count = 0;
}

increment() {
this.count++;
}
}

const counterOne = new Counter();
counterOne.increment();
counterOne.increment();

const counterTwo = counterOne;
counterTwo.increment();

console.log(counterOne.count);
```

- A: `0`
- B: `1`
- C: `2`
- D: `3`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: D

`counterOne` є екземпляром класу `Counter`. Клас `Counter` містить властивість `count` у своєму конструкторі та метод `increment`. Спочатку ми двічі викликали метод `increment`, виконавши `counterOne.increment()`. Наразі `counterOne.count` дорівнює `2`.

<img src="https://i.imgur.com/KxLlTm9.png" width="400">

Потім ми створюємо нову змінну `counterTwo` і встановлюємо їй значення `counterOne`. Оскільки об’єкти взаємодіють за посиланням, ми просто створюємо нове посилання на те саме місце в пам’яті, на яке вказує `counterOne`. Оскільки він має те саме місце в пам’яті, будь-які зміни, внесені до об’єкта, на який посилається `counterTwo`, також застосовуються до `counterOne`. Наразі `counterTwo.count` дорівнює `2`.

Ми викликаємо `counterTwo.increment()`, який змінює `count` на `3`. Потім ми логуємо count у `counterOne`, який повертає `3`.

<img src="https://i.imgur.com/BNBHXmc.png" width="400">

</p>
</details>

---

###### 133. Що буде на виході?

```javascript
const myPromise = Promise.resolve(Promise.resolve('Promise'));

function funcOne() {
setTimeout(() => console.log('Timeout 1!'), 0);
myPromise.then(res => res).then(res => console.log(`${res} 1!`));
console.log('Last line 1!');
}

async function funcTwo() {
const res = await myPromise;
console.log(`${res} 2!`)
setTimeout(() => console.log('Timeout 2!'), 0);
console.log('Last line 2!');
}

funcOne();
funcTwo();
```

- A: `Promise 1! Last line 1! Promise 2! Last line 2! Timeout 1! Timeout 2!`
- B: `Last line 1! Timeout 1! Promise 1! Last line 2! Promise2! Timeout 2! `
- C: `Last line 1! Promise 2! Last line 2! Promise 1! Timeout 1! Timeout 2!`
- D: `Timeout 1! Promise 1! Last line 1! Promise 2! Timeout 2! Last line 2!`

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: C

Спочатку ми викликаємо `funcOne`. У першому рядку `funcOne` ми викликаємо _асинхронну_ функцію `setTimeout`, з якої колбек надсилається до Web API. (перегляньте мою статтю про event loop <a href="https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif">тут</a>.)

Потім ми викликаємо `myPromise` проміс, який є _асинхронною_ операцією.

І проміс, і тайм-аут є асинхронними операціями, функція продовжує працювати, поки виконується проміс та обробляється колбек `setTimeout`. Це означає, що `Last line 1!` логується першим, оскільки це не асинхронна операція.

Оскільки стек викликів ще не порожній, функцію `setTimeout` і проміс в `funcOne` ще не можна додати до стеку викликів.

У `funcTwo` змінна `res` отримує `Проміс`, тому що `Promise.resolve(Promise.resolve('Promise'))` еквівалентна `Promise.resolve('Promise')`, оскільки Promise.resolve просто resolve його значення. `await` у цьому рядку зупиняє виконання функції, доки проміс не вирішиться, а потім продовжує працювати синхронно до завершення, тому `Promise 2!`, а потім `Last line 2!` логуються, а `setTimeout` надсилається до Web API.

Далі стек викликів стає порожнім. Проміси є _мікрозадачами_, тому вони вирішуються першими, коли стек викликів порожній, `Promise 1!` логується.

Тепер, оскільки `funcTwo` не в стеку викликів, стек викликів порожній. Колбеки, які очікують у черзі (`() => console.log("Timeout 1!")` з `funcOne`, і `() => console.log("Timeout 2!")` з `funcTwo`) додалися до стеку викликів один за одним. Перший колбек логує `Timeout 1!` і очищається зі стеку. Потім другий колбек логує `Timeout 2!` і теж видаляється зі стеку.

</p>
</details>

---

###### 134. Як ми можемо викликати `sum` з `sum.js` у `index.js?`

```javascript
// sum.js
export default function sum(x) {
return x + x;
}

// index.js
import * as sum from './sum';
```

- A: `sum(4)`
- B: `sum.sum(4)`
- C: `sum.default(4)`
- D: Експорти за замовчуванням не імпортуються з `*`, лише іменовані експорти

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: C

Із зірочкою `*` ми імпортуємо всі експортовані значення з цього файлу, як за замовчуванням, так і іменовані. Якби у нас був такий файл:

```javascript
// info.js
export const name = 'Lydia';
export const age = 21;
export default 'I love JavaScript';

// index.js
import * as info from './info';
console.log(info);
```

Буде залоговано наступне:

```javascript
{
default: "I love JavaScript",
name: "Lydia",
age: 21
}
```

Для прикладу `sum` це означає, що імпортоване значення `sum` виглядає так:

```javascript
{ default: function sum(x) { return x + x } }
```

Ми можемо викликати цю функцію за допомогою `sum.default`

</p>
</details>

---

###### 135. Що буде на виході?

```javascript
const handler = {
set: () => console.log('Added a new property!'),
get: () => console.log('Accessed a property!'),
};

const person = new Proxy({}, handler);

person.name = 'Lydia';
person.name;
```

- A: `Added a new property!`
- B: `Accessed a property!`
- C: `Added a new property!` `Accessed a property!`
- D: Нічого не буде залоговано

<details><summary><b>Відповідь</b></summary>
<p>

#### Відповідь: C

За допомогою об’єкта `Proxy` ми можемо додати спеціальну поведінку до об’єкта, який ми передаємо йому як другий аргумент. У цьому випадку ми передаємо об’єкт `handler`, який містить дві властивості: `set` і `get`. `set` викликається щоразу, коли ми _встановлюємо_ значення властивості, `get` викликається щоразу, коли ми _отримуємо_ (доступаємося до) значення властивості.

Перший аргумент – це порожній об’єкт `{}`, який є значенням `person`. До цього об’єкта додається спеціальна поведінка, вказана в об’єкті `handler`. Якщо ми додамо властивість до об’єкта `person`, буде викликано `set`. Якщо ми доступаємося до властивості об’єкта `person`, буде викликано `get`.

Спочатку ми додали нову властивість `name` до проксі-об’єкта (`person.name = "Lydia"`). Викликається `set` і логується `"Added a new property!"`.

Потім ми доступаємося до значення властивості проксі-об’єкта, викликається властивість `get`. Логується `"Accessed a property!"`.

</p>
</details>