- [🇸🇦 العربية](../ar-AR/README_AR.md) - [🇪🇬 اللغة العامية](../ar-EG/README_ar-EG.md) - [🇧🇦 Bosanski](../bs-BS/README-bs_BS.md) - [🇩🇪 Deutsch](../de-DE/README.md) - [🇪🇸 Español](../es-ES/README-ES.md) - [🇫🇷 Français](../fr-FR/README_fr-FR.md) - [🇮🇩 Indonesia](../id-ID/README.md) - [🇮🇹 Italiano](../it-IT/README.md) - [🇯🇵 日本語](../ja-JA/README-ja_JA.md) - [🇰🇷 한국어](../ko-KR/README-ko_KR.md) - [🇳🇱 Nederlands](../nl-NL/README.md) - [🇵🇱 Polski](../pl-PL/README.md) - [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md) - [🇷o Română](../ro-RO/README.ro.md) - [🇬🇧 English](../README.md) - [🇽🇰 Shqip](../sq-KS/README_sq_KS.md) - [🇹🇭 ไทย](../th-TH/README-th_TH.md) - [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md) - [🇺🇦 Українська мова](../uk-UA/README.md) - [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md) - [🇨🇳 简体中文](../zh-CN/README-zh_CN.md) - [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md)
#### Ответ: D Внутри функции мы сперва определяем переменную `name` с помощью ключевого слова `var`. Это означает, что переменная будет поднята (область памяти под переменную будет выделена во время фазы создания) со значением `undefined` по умолчанию, до тех пора пока исполнение кода не дойдет до строчки, где определяется переменная. Мы еще не определили значение `name` когда пытаемся вывести её в консоль, поэтому в консоли будет `undefined`. Переменные, определенные с помощью `let` (и `const`), также поднимаются, но в отличие от `var`, не инициализируются. Доступ к ним не возможен до тех пор, пока не выполнится строка их определения (инициализации). Это называется "временная мертвая зона". Когда мы пытаемся обратиться к переменным до того момента как они определены, JavaScript выбрасывает исключение `ReferenceError`.
#### Ответ: C Из-за очереди событий в JavaScript, функция `setTimeout` вызывается _после_ того как цикл будет завершен. Так как переменная `i` в первом цикле была определена с помощью `var`, она будет глобальной. В цикле мы каждый раз увеличиваем значение `i` на `1`, используя унарный оператор `++`. К моменту выполнения функции `setTimeout` значение `i` будет равно `3` в первом примере. Во втором цикле переменная `i` определена с помощью `let`. Такие переменные (а также `const`) имеют блочную область видимости (блок это что угодно между `{ }`). С каждой итерацией `i` будет иметь новое значение, и каждое значение будет замкнуто в своей области видимости внутри цикла.
#### Ответ: B Заметьте, что `diameter` это обычная функция, в то время как `perimeter` это стрелочная функция. У стрелочных функций значение `this` указывает на окружающую область видимости, в отличие от обычных функций! Это значит, что при вызове `perimeter` значение `this` у этой функции указывает не на объект `shape`, а на внешнюю область видимости (например, window). У этого объекта нет ключа `radius`, поэтому возвращается `undefined`.
#### Ответ: A Унарный плюс приводит операнд к числу. `true` это `1`, а `false` это `0`. Строка `'Lydia'` это "истинное" значение. На самом деле мы спрашиваем "является ли это истинное значение ложным"? Ответ: `false`.
#### Ответ: 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`. Это не является валидным, и мы получаем ошибку типа `Cannot read property "size" of undefined`.
#### Ответ: A В JavaScript все объекты являются _ссылочными_ типами данных. Сперва переменная `c` указывает на объект. Затем мы указываем переменной `d` ссылаться на тот же объект, что и `c`. Когда вы изменяете один объект, то изменяются значения всех ссылок, указывающих на этот объект.
#### Ответ: C `new Number()` это встроенный конструктор функции. И хотя он выглядит как число, это не настоящее число: у него есть ряд дополнительных особеннстей, и это объект. Оператор `==` разрешает приведение типов, он проверяет равенство _значений_. Оба значения равны `3`, поэтому возвращается `true`. При использовании оператора `===` значение _и_ тип должны быть одинаковыми. Но в нашем случае это не так: `new Number()` это не число, это **объект**. Оба возвращают `false`.
#### Ответ: D Функция `colorChange` является статической. Статические методы предназначены для работы только в конструкторе, в котором они созданы, и не могут передаваться каким-либо дочерним элементам или вызываться в экземплярах класса. Так как `freddie` является экземпляром класса `Chameleon`, функция не может быть вызвана для него. Будет выдана ошибка `TypeError`.
#### Ответ: A В консоли выведется объект, потому что мы только что создали пустой объект в глобальном объекте! Когда мы вместо `greeting` написали `greetign`, интерпретатор JS на самом деле увидел: 1. `global.greetign = {}` в Node.js 2. `window.greetign = {}`, `frames.geetign = {}` и `self.greetign` в браузерах. 3. `self.greetign` в веб-воркерах. 4. `globalThis.greetign` во всех окружениях. Нужно использовать `"use strict"`, чтобы избежать такого поведения. Эта запись поможет быть уверенным в том, что переменная была определена перед тем как ей присвоили значение.
#### Ответ: A В JavaScript это возможно, т.к. функции это объекты! (Всё есть объект кроме примитивов). Функция — это специальный тип объекта, который можно вызвать. Кроме того, функция — это объект со свойствами. Свойство такого объекта нельзя вызвать, так как оно не является функцией.
#### Ответ: A В JavaScript функции являются объектами, поэтому метод `getFullName` добавляется к самому объекту функции-конструктора. По этой причине мы можем вызвать `Person.getFullName()`, но `member.getFullName` выдает `TypeError`. Если вы хотите, чтобы метод был доступен для всех экземпляров объекта, вы должны добавить его в свойство прототипа: ```js Person.prototype.getFullName = function () { return `${this.firstName} ${this.lastName}`; } ```
#### Ответ: A Для `sarah` мы не использовали ключевое слово `new`. Использование `new` приводит к созданию нового объекта. Но без `new` он указывает на **глобальный объект**! Мы указали, что `this.firstName` равно `"Sarah"` и `this.lastName` равно `"Smith"`. На самом деле мы определили `global.firstName = 'Sarah'` и `global.lastName = 'Smith'`. `sarah` осталась `undefined`, поскольку мы не возвращаем значение из функции `Person`.
#### Ответ: D Во время фазы **захвата** событие распространяется с элементов родителей до элемента цели. После достижения **цели** начинается фаза **всплытия**.
#### Ответ: B Все объекты имеют прототипы, кроме **базового объекта**. Базовый объект — это объект, созданный пользователем, или объект, созданный с использованием ключевого слова `new`. Базовый объект имеет доступ к некоторым методам и свойствам, таким как `.toString`. Вот почему вы можете использовать встроенные методы JavaScript! Все такие способы доступны в прототипе. Хотя JavaScript не может найти метод непосредственно в вашем объекте, он идет вниз по цепочке прототипов и находит его там, что делает его доступным.
#### Ответ: C JavaScript это **динамически типизированный язык**: мы не определяем тип переменных. Переменные могут автоматически быть преобразованы из одного типа в другой без нашего участия, что называется _неявным приведением типов_. **Приведение** это преобразование из одного типа в другой. В этом примере JavaScript сконвертировал число `1` в строку, чтобы операция внутри функции имела смысл и вернула значение. Во время сложения числа (`1`) и строки (`'2'`) число преобразовывается к строке. Мы можем конкатенировать строки вот так: `"Hello" + "World"`. Таким образом, `"1" + "2"` возвращает `"12"`.
#### Ответ: C **Постфиксный** унарный оператор `++`: 1. Возвращает значение (`0`) 2. Инкрементирует значение (теперь число равно `1`) **Префиксный** унарный оператор `++`: 1. Инкрементирует значение (число теперь равно `2`) 2. Возвращает значение (`2`) Результат: `0 2 2`.
#### Ответ: B При использовании [шаблонных строк](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Template_literals) первым аргументом всегда будет массив строковых значений. Оставшимися аргументами будут значения переданных выражений!
#### Ответ: C В операциях сравнения примитивы сравниваются по их _значениям_, а объекты по _ссылкам_. JavaScript проверяет, чтобы объекты указывали на одну и ту же область памяти. Сравниваемые объекты в нашем примере не такие: объект, переданный в качестве параметра, указывает на другую область памяти, чем объекты, используемые в сравнениях. Поэтому `{ age: 18 } === { age: 18 }` и `{ age: 18 } == { age: 18 }` возвращают `false`.
#### Ответ: C Оператор распространения (`...args`) возвращает массив с аргументами. Массив это объект, поэтому `typeof args` возвращает `"object"`.
#### Ответ: C Используя `"use strict"`, можно быть уверенным, что мы по ошибке не побъявим глобальные переменные. Мы ранее нигде не объявляли переменную `age`, поэтому с использованием `"use strict"` возникнет `ReferenceError`. Без использования `"use strict"` ошибки не возникнет, а переменная `age` добавится в глобальный объект.
#### Ответ: A `eval` выполняет код, переданный в виде строки. Если это выражение (как в данном случае), то вычисляется выражение. Выражение `10 * 10 + 5` вернет число `105`.
#### Ответ: B Данные, сохраненные в `sessionStorage` очищаются после закрытия _вкладки_. При использовании `localStorage` данные сохраняются навсегда. Очистить их можно, например, используя `localStorage.clear()`.
#### Ответ: B С помощью ключевого слова `var` можно определять сколько угодно переменных с одним и тем же именем. Переменная будет хранить последнее присвоенное значение. Но такой трюк нельзя проделать с `let` и `const`, т.к. у них блочная область видимости.
#### Ответ: C Все ключи объектов (кроме Symbols) являются строками, даже если заданы не в виде строк. Поэтому `obj.hasOwnProperty('1')` так же возвращает true. Но это не работает для `set`. Значения `'1'` нет в `set`: `set.has('1')` возвращает `false`. Но `set.has(1)` вернет `true`.
#### Ответ: C Если есть два ключа с одинаковым именем, то ключ будет перезаписан. Его позиция сохранится, но значением будет последнее указанное.
#### Ответ: A Базовый контекст исполнения это глобальный контекст исполнения: это то, что доступно где угодно в твоем коде.
#### Ответ: C Оператор `continue` пропускает итерацию, если условие возвращает `true`.
#### Ответ: A `String` это встроенный конструктор, к которому можно добавлять свойства. Я добавила метод к его прототипу. Строки-примитивы автоматически конвертируются к строкам-объектам. Поэтому все строки (строковые объекты) имеют доступ к этому методу!
#### Ответ: B Ключи объекта автоматически конвертируются в строки. Мы собираемся добавить объект в качестве ключа к объекту `a` со значением `123`. Тем не менее, когда мы приводим объект к строке, он становится `"[object Object]"`. Таким образом, мы говорим, что `a["object Object"] = 123`. Потом мы делаем то же самое. `c` это другой объект, который мы неявно приводим к строке. Поэтому `a["object Object"] = 456`. Затем, когда мы выводим `a[b]`, мы имеем в виду `a["object Object"]`. Мы только что установили туда значение `456`, поэтому в результате получаем `456`.
#### Ответ: B Мы вызываем функцию `setTimeout` первой. Тем не менее, она выводится в консоль последней Это происходит из-за того, что в браузерах у нас есть не только рантайм движок, но и `WebAPI`. `WebAPI` предоставляет нам функцию `setTimeout` и много других возможностей. Например, DOM. После того как _коллбек_ отправлен в `WebAPI`, функция `setTimeout` (но не коллбек!) вынимается из стека. Теперь вызывается `foo`, и `"First"` выводится в консоль. `foo` достается из стека, и вызывается `baz`. `"Third"` выводится в консоль. WebAPI не может добавлять содержимое в стек когда захочет. Вместо этого он отправляет коллбек-функцию в так называемую _очередь_. Здесь на сцену выходит цикл событий (event loop). **Event loop** проверяет стек и очередь задач. Если стек пустой, то он берет первый элемент из очереди и отправляет его в стек. Вызывается `bar`, в консоль выводится `"Second"` и эта функция достается из стека.
#### Ответ: C Целью события является самый глубокий вложенный элемент. Остановить распространение событий можно с помощью `event.stopPropagation`
Кликни меня!
#### Ответ: A После клика по `p` будет выведено `p` и `div`. В цикле жизни события есть три фазы: захват, цель и всплытие. По умолчанию обработчики событий выполняются на фазе всплытия (если не установлен параметр `useCapture` в `true`). Всплытие идет с самого глубокого элемента вверх.
#### Ответ: D В обоих случаях мы передаем объект, на который будет указывать `this`. Но `.call` _выполняется сразу же_! `.bind` возвращает _копию_ функции, но с привязанным контекстом. Она не выполняется незамедлительно.
#### Ответ: B Функция `sayHi` возвращает значение, возвращаемое из немедленно вызываемого функционального выражения (IIFE). Результатом является `0` типа `"number"`. Для информации: в JS 8 встроенных типов: `null`, `undefined`, `boolean`, `number`, `string`, `object`, `symbol` и `bigint`. `"function"` не является отдельным типом, т.к. функции являются объектами типа `"object"`.
#### Ответ: A Есть только восемь (8) "ложных" значений: - `undefined` - `null` - `NaN` - `false` - `''` (пустая строка) - `0` - `-0` - `0n` (BigInt(0)) Конструкторы функций, такие как `new Number` и `new Boolean` являются "истинными".
#### Ответ: B `typeof 1` возвращает `"number"`. `typeof "number"` возвращает `"string"`
#### Ответ: C Когда в массив добавляется значение, которое выходит за пределы длины массива, JavaScript создает так называемые "пустые ячейки". На самом деле они имеют значения `undefined`, но в консоли выводятся так: `[1, 2, 3, 7 x empty, 11]` в зависимости от окружения (может отличаться для браузеров, Node, и т.д.).
#### Ответ: A Блок `catch` получает аргумент `x`. Это не тот же `x`, который определен в качестве переменной перед строкой `try {` Затем мы присваиваем этому аргументу значение `1` и устанавливаем значение для переменной `y`. Потом выводим в консоль значение аргумента `x`, которое равно `1`. За пределами блока `catch` переменная `x` все еще `undefined`, а `y` равно `2`. Когда мы вызываем `console.log(x)` за пределами блока `catch`, этот вызов возвращает `undefined`, а `y` возвращает `2`.
#### Ответ: A В JavaScript есть только примитивы и объекты. Типы примитивов: `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, и `symbol`. Отличием примитива от объекта является то, что примитивы не имеют свойств или методов. Тем не менее, `'foo'.toUpperCase()` преобразуется в `'FOO'` и не вызывает `TypeError`. Это происходит потому, что при попытке получения свойства или метода у примитива (например, строки), JavaScript неявно обернет примитив объектом, используя один из классов-оберток (например, `String`), а затем сразу же уничтожит обертку после вычисления выражения. Все примитивы кроме `null` и `undefined` ведут себя таким образом.
#### Ответ: 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]`.
#### Ответ: B `null` - "ложный". `!null` возвращает `true`. `!true` возвращает `false`. `""` - "ложный". `!""` возвращает `true`. `!true` возвращает `false`. `1` - "истинный". `!1` возвращает `false`. `!false` возвращает `true`.
#### Ответ: A Это метод возвращает уникальный id. Этот id может быть использован для очищения интервала с помощью функции `clearInterval()`.
#### Ответ: A Строка является итерируемой сущностью. Оператор распространения преобразовывает каждый символ в отдельный элемент.
#### Ответ: 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.
#### Ответ: B Когда мы передаем несколько промисов методу `Promise.race`, он разрешает/отклоняет _первый_ промис, который разрешается/отклоняется. В метод `setTimeout` мы передаем таймер: 500 мс для первого промиса (`firstPromise`) и 100 мс для второго промиса (`secondPromise`). Это означает, что `secondPromise` разрешается первым со значением `'два'`. `res` теперь содержит значение `'два'`, которое выводиться в консоль.
#### Ответ: D Сначала мы объявляем переменную `person` со значением объекта, у которого есть свойство` name`. Затем мы объявляем переменную с именем `members`. Мы устанавливаем первый элемент этого массива равным значению переменной `person`. Объекты взаимодействуют посредством _ссылок_ при установке их равными друг другу. Когда вы назначаете ссылку из одной переменной в другую, вы создаете _копию_ этой ссылки. (обратите внимание, что у них _не одинаковые_ ссылки!) Затем мы присваиваем переменной `person` значение `null`. Мы изменили только значение переменной `person`, а не первый элемент в массиве, поскольку этот элемент имеет другую (скопированную) ссылку на объект. Первый элемент в `members` по-прежнему содержит ссылку на исходный объект. Когда мы выводим в консоль массив `members`, первый элемент по-прежнему содержит значение объекта, который выводится в консоль.
#### Ответ: B С помощью цикла `for-in` мы можем перебирать ключи объекта, в данном случае `name` и `age`. Под капотом ключи объекта являются строками (если они не являются Symbol). В каждом цикле мы устанавливаем значение `item` равным текущему ключу, по которому он перебирается. Сначала, `item` равен `name`, и выводится в консоль. Затем `item` равен `age`, который выводится в консоль.
#### Ответ: B Ассоциативность операторов - это порядок, в котором компилятор оценивает выражения, слева направо или справа налево. Это происходит только в том случае, если все операторы имеют _одинаковый_ приоритет. У нас есть только один тип оператора: `+`. Кроме того, ассоциативность слева направо. `3 + 4` оценивается первым. Это приводит к числу `7`. `7 + '5'` приводит к `"75"` из-за принуждения. JavaScript преобразует число `7` в строку, см. вопрос 15. Мы можем объединить две строки, используя оператор `+`. `"7" + "5"` приводит к `"75"`.
#### Ответ: C Только первые числа в строке возвращаются. На основе _системы счисления_ (второй аргумент, чтобы указать, к какому типу чисел мы хотим его анализировать: основание 10, шестнадцатеричное, восьмеричное, двоичное и т.д.), `ParseInt` проверяет, являются ли символы в строке допустимыми. Как только он встречает символ, который не является допустимым числом в основании, он прекращает синтаксический анализ и игнорирует следующие символы. `*` не является допустимым числом. Он только разбирает `"7"` в десятичную `7`. `num` теперь содержит значение` 7`.
#### Ответ: C При использовании метода map, значение `num` равно элементу, над которым он в данный момент зацикливается. В этом случае элементы являются числами, поэтому условие оператора if `typeof num === "number"` возвращает `true`. Функция map создает новый массив и вставляет значения, возвращаемые функцией. Однако мы не возвращаем значение. Когда мы не возвращаем значение из функции, функция возвращает значение `undefined`. Для каждого элемента в массиве вызывается функциональный блок, поэтому для каждого элемента мы возвращаем `undefined`.
#### Ответ: A Аргументы передаются _значением_, если их значение не является объектом, то они передаются _ссылкой_. `birthYear` передается по значению, поскольку это строка, а не объект. Когда мы передаем аргументы по значению, создается _копия_ этого значения (см. вопрос 46). Переменная `birthYear` имеет ссылку на значение `"1997"`. Аргумент `year` также имеет ссылку на значение` "1997" `, но это не то же самое значение, на которое имеется ссылка для `birthYear`. Когда мы обновляем значение `year`, устанавливая `year` равным `"1998"`, мы обновляем только значение `year`. `birthYear` по-прежнему равно `"1997"`. Значение `person` является объектом. Аргумент `member` имеет (скопированную) ссылку на _тот же_ объект. Когда мы изменяем свойство объекта, на который `member` ссылается, значение `person` также будет изменено, поскольку они оба имеют ссылку на один и тот же объект. Свойство `name` объекта `person` теперь равно значению `"Lydia"`.
#### Ответ: D С помощью оператора `throw` мы можем создавать собственные ошибки. С этим оператором вы можете генерировать исключения. Исключением может быть строка, число, логическое значение или объект. В этом случае нашим исключением является строка `'Hello world'`. С помощью оператора `catch` мы можем указать, что делать, если в блоке` try` выдается исключение. Исключение: строка `'Hello world'`. `e` теперь равно той строке, которую мы записываем. Это приводит к `'Oh no an error: Hello world'`.
#### Ответ: B Когда вы возвращаете свойство, значение свойства равно _возвращаемому_ значению, а не значению, установленному в функции конструктора. Мы возвращаем строку `"Maserati"`, поэтому `myCar.make` равно `"Maserati"`.
#### Ответ: A `let x = y = 10;` на самом деле является сокращением для: ```javascript y = 10; let x = y; ``` Когда мы устанавливаем `y` равным` 10`, мы фактически добавляем свойство `y` к глобальному объекту (`window` в браузере, `global` в Node). В браузере `window.y` теперь равен` 10`. Затем мы объявляем переменную `x` со значением `y`, которое равно `10`. Переменные, объявленные с ключевым словом `let`, имеют _блочную видимость_, они определены только в блоке, в котором они объявлены; немедленно вызванная функция (IIFE) в этом случае. Когда мы используем оператор `typeof`, операнд `x` не определен: мы пытаемся получить доступ к `x` вне блока, в котором он объявлен. Это означает, что `x` не определен. Значения, которым не присвоено или не объявлено значение, имеют тип `"undefined"`. `console.log(typeof x)` возвращает `"undefined"`. Однако мы создали глобальную переменную `y`, установив `y` равным `10`. Это значение доступно в любом месте нашего кода. `y` определен и содержит значение типа `"number"`. `console.log(typeof y)` возвращает `"number"`.
#### Ответ: A Мы можем удалить свойства из объектов, используя ключевое слово `delete`, также в прототипе. Удаляя свойство в прототипе, оно больше не доступно в цепочке прототипов. В этом случае функция `bark` больше не доступна в прототипе после`delete Dog.prototype.bark`, но мы все еще пытаемся получить к ней доступ. Когда мы пытаемся вызвать что-то, что не является функцией, выдается `TypeError`. В этом случае `TypeError: pet.bark не является функцией`, поскольку` pet.bark` является `undefined`.
#### Ответ: D Объект `Set` является коллекцией _unique_ значений: значение может появляться только один раз в наборе. Мы передали последовательность `[1, 1, 2, 3, 4]` с повторяющимся значением `1`. Поскольку в наборе не может быть двух одинаковых значений, одно из них удаляется. Это приводит к `{1, 2, 3, 4}`.
#### Ответ: C Импортированный модуль является _read-only_: вы не можете изменить импортированный модуль. Только модуль, который их экспортирует, может изменить его значение. Когда мы пытаемся увеличить значение `myCounter`, выдается ошибка: `myCounter` доступен только для чтения и не может быть изменен.
#### Ответ: A Оператор `delete` возвращает логическое значение: `true` при успешном удалении, иначе он вернет `false`. Однако переменные, объявленные с ключевым словом `var`,` const` или `let`, не могут быть удалены с помощью оператора` delete`. Переменная `name` была объявлена с ключевым словом `const`, поэтому ее удаление не было успешным: возвращается `false`. Когда мы устанавливаем `age` равным `21`, мы фактически добавляем свойство с именем `age` к глобальному объекту. Вы можете успешно удалить свойства из объектов, в том числе из глобального объекта, поэтому `delete age` возвращает `true`.
#### Ответ: C Мы можем распаковать значения из массивов или свойств из объектов путем деструктуризации. Например: ```javascript [a, b] = [1, 2]; ``` Значение `a` теперь равно `1`, а значение `b` теперь равно `2`. Что мы на самом деле сделали в этом вопросе, так это: ```javascript [y] = [1, 2, 3, 4, 5]; ``` Это означает, что значение `y` равно первому значению в массиве, которое является числом` 1`. Когда мы регистрируем `y`, возвращается `1`.
#### Ответ: B Можно комбинировать объекты с помощью оператора распространения `...`. Это позволяет создавать копии пар ключ/значение одного объекта и добавлять их в другой объект. В этом случае мы создаем копии объекта `user` и добавляем их в объект `admin`. Объект `admin` теперь содержит скопированные пары ключ/значение, что приводит к `{admin: true, name: "Lydia", age: 21}`.
#### Ответ: B С помощью метода `defineProperty` мы можем добавлять новые свойства к объекту или изменять существующие. Когда мы добавляем свойство к объекту с помощью метода `defineProperty`, они по умолчанию _не перечисляемые_. Метод `Object.keys` возвращает все имена _enumerable_ свойств объекта, в данном случае только `"name"`. Свойства, добавленные с помощью метода `defineProperty`, по умолчанию неизменны. Вы можете переопределить это поведение, используя свойства `writable`, `configurable` и `enumerable`. Таким образом, метод `defineProperty` дает вам гораздо больший контроль над свойствами, которые вы добавляете к объекту.
#### Ответ: A Второй аргумент `JSON.stringify` - это _replacer_. Заменитель может быть либо функцией, либо массивом, и позволяет вам контролировать, что и как должны быть преобразованы в значения. Если заменитель является _массивом_, только свойства, имена которых включены в массив, будут добавлены в строку JSON. В этом случае включаются только свойства с именами `"level"` и `"health"`, `"username"` исключается. `data` теперь равен `"{"level":19, "health":90}"`. Если заменитель является _function_, эта функция вызывается для каждого свойства объекта, который вы преобразуете. Значение, возвращаемое из этой функции, будет значением свойства при добавлении в строку JSON. Если значение равно undefined, это свойство исключается из строки JSON.
#### Ответ: A Унарный оператор `++` _сначала возвращает_ значение операнда, _затем приращивает_ значение операнда. Значение `num1` равно `10`, так как функция увеличений вначале возвращает значение `num`, которое равно `10`, и только затем увеличивает значение `num`. `num2` - это `10`, так как мы передали `num1` в `incpasePassedNumber`. `number` равно `10` (значение `num1`. Опять же, унарный оператор `++` _сначала возвращает_ значение операнда, _затем увеличивает_ значение операнда. Значение `number` равно `10`, поэтому `num2` равно `10`.
#### Ответ: C В ES6 мы можем инициализировать параметры значением по умолчанию. Значением параметра будет значение по умолчанию, если никакое другое значение не было передано функции, или если значение параметра равно `"undefined"`. В этом случае мы распространяем свойства объекта `value` на новый объект, поэтому значение `x` по умолчанию равно `{number: 10}`. Аргумент по умолчанию реализуется в момент _call time_! Каждый раз, когда мы вызываем функцию, создается _new_ объект. Мы вызываем функцию `multiply` первые два раза, не передавая значение: `x` имеет значение по умолчанию `{number: 10}`. Затем мы записываем умноженное значение этого числа, которое равно `20`. В третий раз, когда мы вызываем multiply, мы передаем аргумент: объект с именем `value`. Оператор `*=` на самом деле является сокращением для `x.number = x.number * 2`: мы изменяем значение `x.number` и записываем умноженное значение `20`. В четвертый раз мы снова передаем объект `value`. `x.number` ранее был изменен на `20`, поэтому `x.number * = 2` записывает `40`.
#### Ответ: D Первым аргументом, который получает метод `reduce`, является _аккумулятором_, в данном случае `x`. Второй аргумент - это _текущее значение_, `y`. С помощью метода `reduce` мы выполняем функцию обратного вызова для каждого элемента в массиве, что в конечном итоге может привести к единственному значению. В этом примере мы не возвращаем никаких значений, мы просто регистрируем значения аккумулятора и текущее значение. Значение аккумулятора равно ранее возвращенному значению функции обратного вызова. Если вы не передадите необязательный аргумент `initialValue` методу `reduce`, аккумулятор будет равен первому элементу при первом вызове. При первом вызове аккумулятор (`x`) равен `1`, а текущее значение (`y`) равно `2`. Мы не возвращаемся из функции обратного вызова, мы регистрируем аккумулятор и текущее значение: `1` и `2` регистрируются. Если вы не возвращаете значение из функции, она возвращает значение `undefined`. При следующем вызове аккумулятор равен `undefined`, а текущее значение равно 3. `undefined` и `3` будут зарегистрированы. При четвертом вызове мы снова не возвращаемся из функции обратного вызова. Аккумулятор снова равен `undefined`, а текущее значение равно `4`. `undefined` и` 4` будут зарегистрированы.
#### Ответ: B В производном классе вы не можете получить доступ к ключевому слову `this` до вызова `super`. Если вы попытаетесь это сделать, он выдаст ReferenceError: 1 и 4 приведут к ошибке ссылки. С ключевым словом `super` мы вызываем конструктор родительского класса с заданными аргументами. Конструктор родителя получает аргумент `name`, поэтому нам нужно передать `name` в `super`. Класс `Labrador` получает два аргумента: `name`, поскольку он расширяет `Dog`, и `size` в качестве дополнительного свойства класса `Labrador`. Они оба должны быть переданы в функцию конструктора в `Labrador`, что делается правильно с помощью конструктора 2.
#### Ответ: B С ключевым словом `import` все импортируемые модули являются _pre-parsed_. Это означает, что импортированные модули запускаются _первыми_, код в файле, который импортирует модуль, исполняется _после_. В этом разница между `require()` в CommonJS и `import`! С помощью `require()` вы можете загружать зависимости по требованию во время выполнения кода. Если бы мы использовали `require` вместо `import`, в консоль были бы записаны `running index.js`, `running sum.js`, `3`.
#### Ответ: A Каждый `Symbol` совершенно уникален. Цель аргумента, переданного `Symbol`, состоит в том, чтобы дать `Symbol` описание. Значение `Symbol` не зависит от переданного аргумента. Когда мы проверяем равенство, мы создаем два совершенно новых `Symbol`: первый `Symbol('foo')` и второй `Symbol('foo')`. Эти два значения уникальны и не равны друг другу, `Symbol('foo') === Symbol('foo')` возвращает `false`.
#### Ответ: C С помощью метода `padStart` мы можем добавить отступ в начало строки. Значение, передаваемое этому методу, представляет собой _общую_ длину строки вместе с отступом. Строка `"Lydia Hallie"` имеет длину `12`. `name.padStart(13)` вставляет 1 пробел в начале строки, потому что 12 + 1 равно 13. Если аргумент, переданный методу `padStart`, меньше длины строки, заполнение не будет добавлено.
#### Ответ: A С помощью оператора `+` вы можете объединять строки. В этом случае мы объединяем строку `"🥑"` со строкой `"💻"`, что приводит к `"🥑💻"`.
#### Ответ: C Функция генератора "приостанавливает" выполнение, когда видит ключевое слово yield. Во-первых, мы должны позволить функции выдать строку "Do you love JavaScript?", что можно сделать, вызвав `game.next().value`. Каждая строка выполняется до тех пор, пока не найдет первое ключевое слово `yield`. В первой строке функции есть ключевое слово `yield` на первом месте: выполнение останавливается с первым выходом! _Это означает, что переменная `answer` еще не определена!_ Когда мы вызываем `game.next("Yes").value`, предыдущий `yield` заменяется значением параметров, переданных функции `next()`, в данном случае `"Yes"`. Значение переменной `answer` теперь равно `"Yes"`. Условие if возвращает `false`, а `JavaScript loves you back ❤️`, регистрируется.
#### Ответ: C `String.raw` возвращает строку, в которой экранированные символы (`\n`, `\v`, `\t` и т.д.) игнорируются! Обратная косая черта может быть проблемой, так как вы можете получить что-то вроде: `` const path = `C:\Documents\Projects\table.html` `` Что приведет к: `"C:DocumentsProjects able.html"` С `String.raw` он просто проигнорирует управляющий знак и напечатает: `C:\Documents\Projects\table.html` В этом случае строка `Hello\nworld`, которая и выводится.
#### Ответ: C Асинхронная функция всегда возвращает обещание. `await` все еще должен ждать разрешения обещания: ожидаемое обещание возвращается, когда мы вызываем `getData()`, чтобы установить `data` равным ему. Если бы мы хотели получить доступ к разрешенному значению `"I made it"`, мы могли бы использовать метод `.then()` для `data`: `data.then(res => console.log(res))` Тогда это бы вывело `"I made it!"`
#### Ответ: B Метод `.push()` возвращает _длину_ нового массива! Ранее массив содержал один элемент (строка `"banana"`) и имел длину `1`. После добавления в массив строки `"apple"`, массив содержит два элемента и имеет длину `2`. Это возвращается из функции `addToList`. Метод `push` изменяет исходный массив. Если вы хотите вернуть _массив_ из функции, а не _длину массива_, вы должны были вернуть `list` после добавления в нее `item`.
#### Ответ: B `Object.freeze` делает невозможным добавление, удаление или изменение свойств объекта (если только значение свойства не является другим объектом). Когда мы создаем переменную `shape` и устанавливаем ее равной замороженному объекту `box`, `shape` также ссылается на замороженный объект. Вы можете проверить, заморожен ли объект, используя `Object.isFrozen`. В этом случае `Object.isFrozen(shape)` возвращает true, поскольку переменная `shape` имеет ссылку на замороженный объект. Поскольку `shape` заморожен, и поскольку значение `x` не является объектом, мы не можем изменить свойство `x`. `x` по-прежнему равно `10`, и `{x: 10, y: 20}` регистрируется.
#### Ответ: D Используя [деструктурирующее присваивание](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), мы можем распаковывать значения из массивов или свойства из объектов в отдельные переменные: ```javascript const { firstName } = { firstName: 'Lydia' }; // Версия ES5: // var firstName = { firstName: 'Lydia' }.firstName; console.log(firstName); // "Lydia" ``` Также свойство можно распаковать из объекта и присвоить переменной с именем, отличным от имени свойства объекта: ```javascript const { firstName: myName } = { firstName: 'Lydia' }; // Версия ES5: // var myName = { firstName: 'Lydia' }.firstName; console.log(myName); // "Lydia" console.log(firstName); // Тут будет ошибка Uncaught ReferenceError: firstName is not defined ``` В этом случае `firstName` не существует как переменная, поэтому попытка доступа к ее значению вызовет `ReferenceError`. **Примечание.** Помните о свойствах глобальной области видимости: ```javascript const { name: myName } = { name: 'Lydia' }; console.log(myName); // "lydia" console.log(name); // "" ----- Браузер, например, Chrome console.log(name); // ReferenceError: name is not defined ----- NodeJS ``` Всякий раз, когда Javascript не может найти переменную в _текущей области видимости_, то поднимается вверх по [цепочке областей видимости](https://developer.mozilla.org/ru/docs/Web/JavaScript/Closures#лексическая_область_видимости) и ищет ее на каждом уровне, и если достигает области верхнего уровня, также известной как **Глобальная область**, и все еще не находит нужной ссылки, то выдает `ReferenceError`. - В **браузерах**, таких как _Chrome_, `name` является _устаревшим свойством глобальной области_. В этом примере код выполняется внутри _глобальной области_ и нет определяемой пользователем локальной переменной `name`, поэтому интерпретатор ищет предопределенные _переменные/свойства_ в глобальной области видимости, что в случае браузеров происходит через объект `window` и возвращается значение [window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name), которое равно **пустой строке**. - В **NodeJS** такого свойства в "глобальном" объекте нет, поэтому попытка доступа к несуществующей переменной вызовет [ReferenceError](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Errors/Not_defined).
#### Ответ: A Чистая функция - это функция, которая всегда возвращает тот же результат, если переданы одинаковые аргументы. Функция `sum` всегда возвращает один и тот же результат. Если мы передадим `1` и `2`, он всегда вернет `3` без побочных эффектов. Если мы передадим `5` и `10`, он всегда вернет `15` и так далее. Это определение чистой функции.
#### Ответ: C Функция `add` является функцией _запоминателем_. С помощью запоминания мы можем кэшировать результаты функции, чтобы ускорить ее выполнение. В этом случае мы создаем объект `cache`, в котором хранятся ранее возвращенные значения. Если мы снова вызываем функцию `addFunction` с тем же аргументом, она сначала проверяет, получило ли оно уже это значение в своем кеше. В этом случае будет возвращено значение кэша, что экономит время выполнения. Иначе, если он не кэшируется, он вычислит значение и сохранит его после. Мы вызываем функцию `addFunction` три раза с одним и тем же значением: при первом вызове значение функции, когда `num` равно `10`, еще не кэшировано. Условие оператора if `num in cache` возвращает `false`, и выполняется блок else: `Calculated! 20` регистрируется, и значение результата добавляется в объект кеша. `cache` теперь выглядит как `{10: 20}`. Во второй раз объект `cache` содержит значение, возвращаемое для `10`. Условие оператора if `num in cache` возвращает `true`, а `'From cache! 20'` выводится в лог. В третий раз мы передаем `5 * 2` в функцию, которая оценивается как `10`. Объект `cache` содержит значение, возвращаемое для `10`. Условие оператора if `num in cache` возвращает `true`, а `'From cache! 20'` регистрируется.
#### Ответ: A С помощью цикла _for-in_ мы можем перебирать **перечисляемые** свойства. В массиве перечисляемые свойства являются "ключами" элементов массива, которые фактически являются их индексами. Вы можете увидеть массив как: `{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}` Где ключи - перечисляемые свойства. `0` `1` `2` `3` войти в систему. С помощью цикла _for-of_ мы можем выполнять итерацию **итераций**. Массив является итеративным. Когда мы выполняем итерацию по массиву, переменная "item" равна элементу, по которому она итерируется в данный момент, `"☕"` `"💻"` `"🍷"` `"🍫"` выводится в лог.
#### Ответ: C Элементы массива могут содержать любые значения. Числа, строки, объекты, другие массивы, ноль, логические значения, неопределенные и другие выражения, такие как даты, функции и вычисления. Элемент будет равен возвращаемому значению. `1 + 2` вернет `3`, `1 * 2` вернет `2`, а `1 / 2` вернет `0.5`.
#### Ответ: B По умолчанию аргументы имеют значение `undefined`, если только значение не было передано функции. В этом случае мы не передали значение для аргумента `name`. `name` равно логгируемому `undefined`. В ES6 мы можем перезаписать значение по умолчанию `undefined` параметрами по умолчанию. Например: `function sayHi(name = "Lydia") { ... }` В этом случае, если мы не передали значение или если мы передали `undefined`, `name` всегда будет равно строке `Lydia`
#### Ответ: B Значение ключевого слова `this` зависит от того, где вы его используете. В **методе**, как и в методе `getStatus`, ключевое слово `this` ссылается на объект, которому принадлежит метод. Метод принадлежит объекту `data`, поэтому `this` относится к объекту `data`. Когда мы регистрируем `this.status`, регистрируется свойство `status` объекта `data`, которое является `"🥑"`. С помощью метода `call` мы можем изменить объект, на который ссылается ключевое слово `this`. В **функциях** ключевое слово `this` относится к _объекту, которому принадлежит функция_. Мы объявили функцию `setTimeout` для объекта _global_, поэтому в функции `setTimeout` ключевое слово `this` ссылается на объект _global_. В глобальном объекте есть переменная с именем _status_ со значением `"😎"`. При регистрации `this.status` выводится `"😎"`.
#### Ответ: A Мы устанавливаем переменную `city` равной значению свойства с именем `city` для объекта `person`. У этого объекта нет свойства с именем `city`, поэтому переменная `city` имеет значение `undefined`. Обратите внимание, что мы _не_ ссылаемся на сам объект person! Мы просто устанавливаем переменную `city` равной текущему значению свойства `city` объекта `person`. Затем мы устанавливаем `city` равным строке `"Amsterdam"`. Это не меняет объект person - нет ссылки на этот объект. При регистрации объекта `person` возвращается неизмененный объект.
#### Ответ: C Переменные с ключевыми словами `const` и `let` имеют _блочную видимость_. Блок - это что-то между фигурными скобками (`{}`). В этом случае в фигурных скобках операторов if/else. Вы не можете ссылаться на переменную за пределами блока, в котором она объявлена, вызывается ReferenceError.
#### Ответ: C Значение `res` во втором `.then` равно возвращенному значению предыдущего `.then`. Вы можете продолжать цепочку `.then` таким образом; значение передается следующему обработчику.
#### Ответ: A С помощью `!!name` мы определяем, является ли значение `name` истинным или ложным. Если имя истинное, которое мы хотим проверить, то `!name` возвращает `false`. А `!false` (это то, чем на самом деле является `!! name`) возвращает `true`. Устанавливая `hasName` равным `name`, вы устанавливаете `hasName` равным любому значению, которое вы передали функции `getName`, а не логическому значению `true`. `new Boolean (true)` возвращает объектную оболочку, а не само логическое значение. `name.length` возвращает длину переданного аргумента, независимо от того, является ли он `true`.
#### Ответ: B Чтобы получить символ по определенному индексу в строке, вы можете использовать скобочную нотацию. Первый символ в строке имеет индекс 0 и т.д. В этом случае мы хотим получить элемент с индексом 0, символ `'I'`, который выводится в лог. Обратите внимание, что этот метод не поддерживается в IE7 и ниже. В этом случае используйте `.charAt()`
#### Ответ: B Вы можете установить значение параметра по умолчанию равным другому параметру функции, если они были определены _до_ параметров по умолчанию. Мы передаем значение `10` в функцию `sum`. Если функция `sum` принимает только один аргумент, это означает, что значение для `num2` не передано, и в этом случае значение `num1` равно переданному значению `10`. Значением по умолчанию `num2` является значение `num1`, которое равно `10`. `num1 + num2` возвращает `20`. Если вы пытаетесь установить значение параметра по умолчанию равным параметру, который определен _после_ (справа), то значение параметра еще не было инициализировано; это приведет к ошибке.
#### Ответ: A С синтаксисом `import * as name` мы импортируем _все exports_ из файла `module.js` в файл `index.js`, тогда и создается новый объект с именем `data`. В файле `module.js` есть два экспорта: экспорт по умолчанию и именованный экспорт. Экспорт по умолчанию - это функция, которая возвращает строку `"Hello World"`, а именованный экспорт - это переменная с именем `name`, которая имеет значение строки `"Lydia"`. Объект `data` имеет свойство `default` для экспорта по умолчанию, другие свойства имеют имена именованных экспортов и их соответствующие значения.
#### Ответ: C Классы являются синтаксическим сахаром для конструкторов функций. Эквивалентом класса `Person` в качестве конструктора функции будет: ```javascript function Person() { this.name = name } ``` Вызов конструктора функции с `new` приводит к созданию экземпляра `Person`, ключевое слово `typeof` возвращает `"object"` для экземпляра. `typeof member` возвращает `"object"`.
#### Ответ: D Метод `.push` возвращает _новую длину_ массива, а не сам массив! Устанавливая `newList` равным `[1, 2, 3].push(4)`, мы устанавливаем `newList` равным новой длине массива: `4`. Затем мы пытаемся использовать метод `.push` для `newList`. Поскольку `newList` является числовым значением `4`, мы не можем использовать метод `.push`: выдается ошибка TypeError.
#### Ответ: D Обычные функции, такие как функция `giveLydiaPizza`, имеют свойство `prototype`, которое является объектом (прототипом объекта) со свойством `constructor`. Однако функции со стрелками, такие как функция `giveLydiaChocolate`, не имеют этого свойства `prototype`. `undefined` возвращается при попытке доступа к свойству `prototype` с использованием `giveLydiaChocolate.prototype`.
#### Ответ: A `Object.entries (person)` возвращает массив вложенных массивов, содержащий ключи и объекты: `[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]` Используя цикл `for-of`, мы можем перебирать каждый элемент массива, в данном случае подмассивы. Мы можем мгновенно деструктурировать подмассивы в цикле for, используя `const [x, y]`. `x` равен первому элементу в подмассиве, `y` равен второму элементу в подмассиве. Первым подмассивом является `[ "name", "Lydia" ]`, где `x` равно `"name"`, и `y` равно `"Lydia"`, которые выводятся в лог. Вторым подмассивом является `[ "age", 21 ]`, где `x` равно `"age"`, и `y` равно `21`, которые выводятся в лог.
#### Ответ: D `... args` - прочие параметры. Значение прочих параметров - это массив, содержащий все оставшиеся аргументы **и может быть передан только последним**! В этом примере прочие параметры были вторым аргументом. Это невозможно, и это приведет к синтаксической ошибке. ```javascript function getItems(fruitList, favoriteFruit, ...args) { return [...fruitList, ...args, favoriteFruit] } getItems(["banana", "apple"], "pear", "orange") ``` Приведенный выше пример работает. Это возвращает массив `[ 'banana', 'apple', 'orange', 'pear' ]`
#### Ответ: B В JavaScript мы _не должны_ явно указывать точку с запятой (`;`), однако движок JavaScript все равно добавляет их после операторов. Это называется **автоматической вставкой точек с запятой**. Например, оператором могут быть переменные или ключевые слова, такие как `throw`, `return`, `break` и т.д. Здесь мы написали инструкцию `return` и другое значение `a + b` в новой строке. Однако, поскольку это новая линия, движок не знает, что это на самом деле значение, которое мы хотели бы вернуть. Вместо этого он автоматически добавляет точку с запятой после `return`. Вы можете увидеть это как: ```javascript return; a + b ``` Это означает, что `a + b` никогда не достигается, так как функция перестает выполняться после ключевого слова `return`. Если значение не возвращается, как здесь, функция возвращает значение `undefined`. Обратите внимание, что после операторов `if / else` автоматической вставки нет!
#### Ответ: B Мы можем установить классы равными другим классам/конструкторам функций. В этом случае мы устанавливаем `Person` равным `AnotherPerson`. Свойство `name` этого конструктора - `Sarah`, поэтому свойство `name` для нового экземпляра класса `Person` `member` - это `Sarah`.
#### Ответ: D `Symbol` не является _перечисляемый_. Метод `Object.keys` возвращает все _перечисляемые_ свойства ключа для объекта. `Symbol` не просматривается таким образом, и возвращается пустой массив. При регистрации всего объекта будут видны все свойства, даже не перечисляемые. Это одно из многих качеств символа: помимо представления совершенно уникального значения (которое предотвращает случайное столкновение имен в объектах, например, при работе с 2 библиотеками, которые хотят добавить свойства к одному и тому же объекту), вы также можете "скрыть" свойства объектов таким образом (хотя и не полностью. Вы можете получить доступ к символам, используя метод `Object.getOwnPropertySymbols()`).
#### Ответ: A Функция `getList` получает массив в качестве аргумента. Между скобками функции `getList` мы сразу же деструктурируем этот массив. Вы можете увидеть это как: `[x, ...y] = [1, 2, 3, 4]` С помощью оставшихся параметров `... y` мы помещаем все "оставшиеся" аргументы в массив. Остальные аргументы - это `2`, `3` и `4` в этом случае. Значение `y` является массивом, содержащим все остальные параметры. В этом случае значение `x` равно `1`, поэтому, мы видим в логе `[x, y]`, `[1, [2, 3, 4]]`. Функция `getUser` получает объект. В стрелочных функциях нам _не нужно_ писать фигурные скобки, если мы просто возвращаем одно значение. Однако, если вы хотите мгновенно вернуть _object_ из стрелочной функции, вы должны написать его между круглыми скобками, иначе все, что находится между двумя фигурными скобками, будет интерпретироваться как оператор блока. В этом случае код между фигурными скобками не является допустимым кодом JavaScript, поэтому выдается `SyntaxError`. Следующая функция вернула бы объект: ```const getUser = user => ({ name: user.name, age: user.age })```
#### Ответ: C Переменная `name` содержит значение строки, которая не является функцией, поэтому не может вызываться. Ошибки типа выдаются, когда значение не соответствует ожидаемому типу. JavaScript ожидал, что `name` будет функцией, так как мы пытаемся вызвать ее. Однако это была строка, поэтому выдается ошибка TypeError: name не является функцией! Синтаксические ошибки генерируются, когда вы написали что-то, что не является допустимым JavaScript, например, когда вы написали слово `return` как `retrun`. ReferenceErrors генерируется, когда JavaScript не может найти ссылку на значение, к которому вы пытаетесь получить доступ.
#### Ответ: B `[]` - истинное значение. С оператором `&&` будет возвращено правое значение, если левое значение является истинным значением. В этом случае левое значение `[]` является истинным значением, поэтому возвращается `'Im'`. `""` - ложное значение. Если левое значение ложно, ничего не возвращается. `n't` не возвращается.
#### Ответ: C С помощью оператора `||` мы можем вернуть первый истинный операнд. Если все значения ложны, последний операнд возвращается. `(false || {} || null)`: пустой объект `{}` является истинным значением. Это первое (и единственное) истинное значение, которое возвращается. `one` содержит `{}`. `(null || false || "")`: все операнды являются ложными значениями. Это означает, что прошедший операнд `""` возвращается. `two` содержит `""`. `([] || 0 || "")`: пустой массив `[]` является истинным значением. Это первое истинное значение, которое возвращается. `three` присвоено `[]`.
#### Ответ: D С обещанием мы в основном говорим: _"Я хочу выполнить эту функцию и откладываю ее, пока она выполняется, поскольку это может занять некоторое время. Только когда определенное значение разрешено (или отклонено), и когда стек вызовов пуст, я хочу использовать это значение_". Мы можем получить это значение с помощью ключевого слова `.then` и `await` в функции `async`. Хотя мы можем получить значение обещания с помощью `.then` и `await`, они работают немного по-разному. В `firstFunction` мы (вроде) отложили функцию `myPromise` во время ее работы, но продолжили выполнение другого кода, в данном случае `console.log ('second')`. Затем функция разрешается строкой `I have resolved`, которая затем логируется после того, как она увидела, что стек вызовов пуст. Используя ключевое слово `await` в `secondFunction`, мы буквально приостанавливаем выполнение асинхронной функции до тех пор, пока значение не будет разрешено до перехода на следующую строку. Это означает, что мы ожидали разрешения `myPromise` со значением `I have resolved`, и только когда это произошло, мы перешли к следующей строке: `second` была выведена в консоль последней.
#### Ответ: C Оператор `+` используется не только для добавления числовых значений, но мы также можем использовать его для объединения строк. Всякий раз, когда движок JavaScript видит, что одно или несколько значений не являются числом, он приводит число к строке. Первым является `1`, который является числовым значением. `1 + 2` возвращает число `3`. Тем не менее, вторая строка `"Lydia"`. `"Lydia"` является строкой, а `2` является числом: `2` приводится к строке. `"Lydia"` и `"2"` объединяются, что приводит к результирующей строке `"Lydia2"`. `{name: "Lydia"}` является объектом. Ни число, ни объект не являются строкой, поэтому они приводятся к строке. Всякий раз, когда мы приводим обычный объект, он становится `"[object Object]"`. `"[object Object]"`, объединенный с `"2"`, становится `"[object Object]2"`.
#### Ответ: C
Мы можем передать любой тип значения, которое мы хотим, в `Promise.resolve`, либо обещание, либо не обещание. Сам метод возвращает обещание с разрешенным значением (`
#### Ответ: B Объекты передаются по ссылке. Когда мы проверяем объекты на строгое равенство (`===`), мы сравниваем их ссылки. Мы устанавливаем значение по умолчанию для `person2`, равное объекту `person`, и передаем объект `person` в качестве значения для `person1`. Это означает, что оба значения имеют ссылку на одно и то же место в памяти, поэтому они равны. Блок кода в операторе `else` запускается, и в лог выводится `They are the same!`.
#### Ответ: D В JavaScript у нас есть два способа доступа к свойствам объекта: нотация в скобках или нотация в точках. В этом примере мы используем точечную нотацию (`colorConfig.colors`) вместо скобочной нотации (`colorConfig["colors"]`). В точечной нотации JavaScript пытается найти свойство объекта с таким точным именем. В этом примере JavaScript пытается найти свойство с именем `colors` в объекте `colorConfig`. Не существует свойства с именем `colors`, поэтому возвращается `undefined`. Затем мы пытаемся получить доступ к значению первого элемента, используя `[1]`. Мы не можем сделать это для значения, которое `undefined`, поэтому оно выдает `TypeError`: `Cannot read свойство '1' of undefined`. JavaScript интерпретирует (или распаковывает) операторы. Когда мы используем скобочные обозначения, он видит первую открывающую скобку `[` и продолжает работать, пока не найдет закрывающую скобку `]`. Только тогда он оценит утверждение. Если бы мы использовали `colorConfig[colors [1]]`, он бы возвратил значение свойства `red` объекта `colorConfig`.
#### Ответ: A Под капотом смайлики - это юникоды. Юникод для сердца смайликов `"U+2764 U+FE0F"`. Они всегда одинаковы для одного и того же смайлика, поэтому мы сравниваем две одинаковые строки друг с другом, что возвращает `true`.
#### Ответ: D Используя метод `splice`, мы модифицируем исходный массив, удаляя, заменяя или добавляя элементы. В этом случае мы удалили 2 элемента из индекса 1 (мы удалили `'🥑'` и `'😍'`) и добавили `✨` emoji. `map`, `filter` и `slice` возвращают новый массив, `find` возвращает элемент, а `reduce` возвращает аккумулированное значение.
#### Ответ: A Мы устанавливаем значение свойства `favourFood` для объекта `info` равным строке со смайликами для пиццы, `'🍕'`. Строка является примитивным типом данных. В JavaScript примитивные типы данных передаются по ссылке ... В JavaScript примитивные типы данных (все, что не является объектом) передаются как _значение_. В этом случае мы устанавливаем значение свойства `favourFood` объекта `info` равным значению первого элемента в массиве `food`, в данном случае это строка с emoji пиццы (`'🍕'`). Строка является примитивным типом данных и взаимодействует по значению (см. мой [пост в блоге](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference), если вы заинтересованы в получении дополнительной информации). Затем мы меняем значение свойства `favourFood` объекта `info`. Массив `food` не изменился, поскольку значение `favourFood` было просто _скопировано_ из значения первого элемента в массиве и не имеет ссылки на то же место в памяти, что и элемент на `food[0]`. Когда мы выводим в лог `food`, это все равно исходный массив, `['🍕', '🍫', '🥑', '🍔']`.
#### Ответ: A С помощью метода `JSON.parse ()` мы можем разобрать строку JSON в значение JavaScript. ```javascript // Преобразование числа в допустимый JSON, затем преобразование строки JSON в значение JavaScript: const jsonNumber = JSON.stringify(4) // '4' JSON.parse(jsonNumber) // 4 // Преобразование значения массива в допустимый JSON, затем разбор строки JSON в значение JavaScript: const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]' JSON.parse(jsonArray) // [1, 2, 3] // Преобразование объекта в допустимый JSON, затем преобразование строки JSON в значение JavaScript: const jsonArray = JSON.stringify({ name: 'Lydia' }) // '{"name":"Lydia"}' JSON.parse(jsonArray) // { name: 'Lydia' } ```
#### Ответ: D Каждая функция имеет свой собственный _контекст исполнения_ (или _область видимости_). Функция `getName` сначала ищет в своем собственном контексте (области видимости), чтобы увидеть, содержит ли она переменную `name`, к которой мы пытаемся получить доступ. В этом случае функция `getName` содержит собственную переменную `name`: мы объявляем переменную `name` с ключевым словом `let` и значением `'Sarah'`. Переменные с ключевым словом `let` (и `const`) поднимаются в начало функции, в отличие от `var`, которые не инициализируется. Они недоступны до того, как мы объявим (инициализируем) их строку. Это называется "временной мертвой зоной". Когда мы пытаемся получить доступ к переменным до их объявления, JavaScript выдает `ReferenceError`. Если бы мы не объявили переменную `name` в функции `getName`, движок javascript посмотрел бы вниз по _цепочки области действия_. Внешняя область имеет переменную с именем `name` со значением `Lydia`. В этом случае он бы записал `Lydia`. ```javascript let name = 'Lydia' function getName() { console.log(name) } getName() // Lydia ```
#### Ответ: C Используя ключевое слово `yield`, мы получаем значения в функции генератора. С помощью ключевого слова `yield*` мы можем получить значения из другой функции-генератора или итерируемого объекта (например, массива). В `generatorOne` мы получаем весь массив `['a', 'b', 'c']`, используя ключевое слово `yield`. Значение свойства `value` для объекта, возвращаемого методом `next` для `one` (`one.next().value`), равно всему массиву `['a', 'b', 'c']`. ```javascript console.log(one.next().value) // ['a', 'b', 'c'] console.log(one.next().value) // undefined ``` В файле `generatorTwo` мы используем ключевое слово `yield*`. Это означает, что первое полученное значение `two` равно первому полученному значению в итераторе. Итератор - это массив `['a', 'b', 'c']`. Первым полученным значением является `a`, поэтому в первый раз, когда мы вызываем `two.next().value`, возвращается `a`. ```javascript console.log(two.next().value) // 'a' console.log(two.next().value) // 'b' console.log(two.next().value) // 'c' console.log(two.next().value) // undefined ```
#### Ответ: A Выражения внутри литералов шаблона расчитываются первыми. Это означает, что строка будет содержать возвращаемое значение выражения, в данном случае немедленно исполняемую функцию `(x => x)('I love')`. Мы передаем значение `'I love'` в качестве аргумента стрелочной функции `x => x`. `x` равно `'I love'`, которое и возвращается. Это приводит к `I love to program`.
#### Ответ: C Обычно, когда мы устанавливаем объекты равными `null`, эти объекты получают статус _собрано в мусор_, так как больше нет ссылок на этот объект. Однако, поскольку функция обратного вызова внутри `setInterval` является стрелочной функцией (таким образом, привязанной к объекту `config`), функция обратного вызова по-прежнему содержит ссылку на объект `config`. Пока есть ссылка, объект не будет собирать мусор. Так как это интервал, установка `config` в `null` или `delete`-ing `config.alert` не приведет к сбору мусора для интервала, поэтому интервал все равно будет вызываться. Его следует очистить с помощью `clearInterval(config.alert)`, чтобы удалить его из памяти. Поскольку он не был очищен, функция обратного вызова `setInterval` будет по-прежнему вызываться каждые 1000мс (1с).
#### Ответ: B При добавлении пары ключ/значение с использованием метода `set` имя ключа будет равно значению первого аргумента, переданного в функцию `set`, а значением будет второй аргумент, переданный в функцию `set`. В данном случае ключом является _функция_ `() => 'greeting'` и значение `'Hello world'`. `myMap` теперь это `{ () => 'greeting' => 'Hello world!' }`. 1 неверно, поскольку ключ не `'greeting'`, а `() => 'greeting'`. 3 неверно, так как мы создаем новую функцию, передавая ее в качестве параметра методу `get`. Объект взаимодействует со _ссылкой_. Функции - это объекты, поэтому две функции никогда не бывают строго равными, даже если они идентичны: они имеют ссылки на разные места в памяти.
#### Ответ: C Функции `changeAge` и `changeAgeAndName` имеют параметр по умолчанию, а именно _вновь_ созданный объект `{ ...person }`. Этот объект имеет копии всех ключей/значений объекта `person`. Сначала мы вызываем функцию `changeAge` и передаем объект `person` в качестве аргумента. Эта функция увеличивает значение свойства `age` на 1. `person` теперь `{name: "Lydia", age: 22}`. Затем мы вызываем функцию `changeAgeAndName`, однако мы не передаем параметр. Вместо этого значение `x` равно новому объекту: `{ ... person }`. Поскольку это новый объект, он не влияет на значения свойств объекта `person`. `person` по-прежнему равен `{name: "Lydia", age: 22}`.
#### Ответ: C С помощью оператора распространения (spread) `...` мы можем _распределить_ итерации в отдельньные элементы. `sumValues` принимает три аргумента:`x`, `y` и `z`. `...[1, 2, 3]` приведет к перечню `1, 2, 3`, который мы передаем функции `sumValues`.
#### Ответ: B С операндом `+=` мы увеличиваем значение `num` на `1`. `num` имеет начальное значение `1`, поэтому `1 + 1` равно `2`. Элементом второго индекса в массиве `list` и является вывод `console.log (list [2])`🥰.
#### Ответ: B С необязательным оператором связывания `?.` нам больше не нужно явно проверять, действительны ли более глубокие вложенные значения или нет. Если мы пытаемся получить доступ к свойству со (_нулевым_) значением `undefined` или `null`, выражение замыкается и возвращает `undefined`. `person.pet?.name`: `person` имеет свойство с именем `pet`: `person.pet` не нулевое. Оно имеет свойство с именем `name`, и возвращает `Mara`. `person.pet?.family?.name`: `person` имеет свойство с именем `pet`: `person.pet` не нулевое. `pet` _не_ имеет свойство с именем `family`, `person.pet.family` нулевое. Выражение возвращает `undefined`. `person.getFullName?.()`: `person` имеет свойство с именем `getFullName`: `person.getFullName()` не нулевое, и может быть вызвано, возвращает `Lydia Hallie`. `member.getLastName?.()`: `member` не определено: `member.getLastName()` нулевое. Выражение возвращает `undefined`.
#### Ответ: B Мы передали условие `groceries.indexOf("banana")` в оператор `if`. `groceries.indexOf("banana")` возвращает `0`, что является ложным значением. Поскольку условие в операторе `if` ложно, выполняется код в блоке `else`, и в лог выводится ``We don't have to buy bananas!``.
#### Ответ: D Метод `language` является `сеттером`. Сеттеры не содержат действительного значения, их целью является изменение свойств. При вызове метода `setter` возвращается `undefined`.
#### Ответ: C `typeof name` возвращает `"строку"`. Строка `"string"` является истинным значением, поэтому `!typeof name` возвращает логическое значение `false`. `false === "object"` и `false === "string"` оба возвращают `false`. (Если бы мы хотели проверить, был ли тип (не)равен определенному типу, мы должны были написать `!==` вместо `!typeof`)
#### Ответ: A Функция `add` возвращает стрелочную функцию, которая возвращает стрелочную функцию, которая возвращает стрелочную функцию (все еще тут?). Первая функция получает аргумент `x` со значением `4`. Мы вызываем вторую функцию, которая получает аргумент `y` со значением `5`. Затем мы вызываем третью функцию, которая получает аргумент `z` со значением `6`. Когда мы пытаемся получить доступ к значениям `x`, `y` и `z` в функции последней стрелки, движок JS поднимается вверх по цепочке областей видимости, чтобы найти значения для `x` и `y` соответственно. Это возвращает `4` `5` `6`.
#### Ответ: C Функция генератора `range` возвращает асинхронный объект с обещаниями для каждого элемента в диапазоне, который мы передаем: `Promise {1}`, `Promise {2}`, `Promise {3}`. Мы устанавливаем переменную `gen` равной асинхронному объекту, после чего зацикливаем ее, используя цикл `for await ... of`. Мы устанавливаем переменную `item` равной возвращаемым значениям `Promise`: сначала `Promise {1}`, затем `Promise {2}`, затем `Promise {3}`. Так как мы _ожидаем_ значение `item`, разрешается обещание, возвращаются разрешенные _значения_ обещания: `1`, `2`, затем `3`.
#### Ответ: D `myFunc` ожидает объект со свойствами `x`, `y` и `z` в качестве аргумента. Поскольку мы передаем только три отдельных числовых значения (1, 2, 3) вместо одного объекта со свойствами `x`, `y` и `z` ({x: 1, y: 2, z: 3}), то `x`, `y` и `z` имеют значение по умолчанию` undefined`.
#### Ответ: B С помощью метода `Intl.NumberFormat` мы можем форматировать числовые значения в любой локали. Мы форматируем числовое значение `130` для локали `en-US` как `unit` в `mile-per-hour`, что приводит к `130 mph`. Числовое значение `300` для локали `en-US` в качестве `currentcy` в `USD` приводит к `$300.00`.
#### Ответ: B Деструктурируя объекты, мы можем распаковать значения из правого объекта и присвоить распакованному значению значение того же по имени свойства в левом объекте. В этом случае мы присваиваем значение "💀" `spookyItems[3]`. Это означает, что мы модифицируем массив `spookyItems`, добавляем к нему «💀». При логировании `spookyItems` выводится ` ["👻", "🎃", "🕸", "💀"]`.
#### Ответ: C С помощью метода `Number.isNaN` вы можете проверить, является ли передаваемое вами значение _числовым значением_ и равно ли оно `NaN`. `name` не является числовым значением, поэтому `Number.isNaN(name)` возвращает `false`. `age` является числовым значением, но не равно `NaN`, поэтому `Number.isNaN(age)` возвращает `false`. С помощью метода `isNaN` вы можете проверить, не является ли передаваемое вами значение числом. `name` не является числом, поэтому `isNaN(name)` возвращает true. `age` - это число, поэтому `isNaN(age)` возвращает `false`.
#### Ответ: D Переменные, объявленные с ключевым словом `const`, не имеют ссылки до их инициализации: это называется _временная мертвая зона_. В функции `getInfo` переменная `randomValue` находится в области видимости `getInfo`. В строке, где мы хотим записать значение `typeof randomValue`, переменная `randomValue` еще не инициализирована: выдается `ReferenceError`! Движок не пошел по цепочке областей видимости, так как мы объявили переменную `randomValue` в функции `getInfo`.
#### Ответ: C В блоке `try` мы выводим в лог ожидаемое значение переменной `myPromise`: `"Woah some cool data"`. Поскольку в блоке `try` не было выдано никаких ошибок, код в блоке `catch` не запускается. Код в блоке `finally` _всегда_ выполняется, `"Oh finally!"` также выводится в лог.
#### Ответ: B С помощью метода `flat` мы можем создать новый плоский массив. Глубина уплощенного массива зависит от значения, которое мы передаем. В этом случае мы передали значение `1` (которое нам не нужно, это значение по умолчанию), что означает, что будут объединены только массивы на первой глубине. `['🥑']` и `['✨', '✨', ['🍕', '🍕']]` в этом случае. Конкатенация этих двух массивов приводит к `['🥑', '✨', '✨', ['🍕', '🍕']]`.
#### Ответ: D `counterOne` экземпляр класса `Counter`. Counter класс содержит метод `increment` и свойство `count` в конструкторе. Сперва, при помощи `counterOne.increment()`, мы дважды вызываем метод `increment`. `counterOne.count` становится `2`. Затем, мы создаем новую переменную `counterTwo`, и присваиваем ей `counterOne`. Поскольку объекты передаются по ссылке, мы просто создаем новую ссылку на то же место в памяти, на которое указывает `counterOne`. Поскольку переменные ссылаются на то же место в памяти, любые изменения, внесенные в объект, на который ссылается `counterTwo`, также применяются к` counterOne`. Теперь `counterTwo.count` равно `2`. Мы вызываем `counterTwo.increment()`, что устанавливает значение `count` равное `3`. Затем мы выводим в консоль значение переменной `counterOne`, которое равно `3`.
#### Ответ: D Сначала мы вызываем `funcOne`. В первой строке `funcOne` мы вызываем _асинхронную_ функцию `setTimeout`, из которой обратный вызов отправляется в веб-API. (см. мою статью о цикле событий здесь.) Затем мы вызываем обещание `myPromise`, которое является _асинхронной_ операцией. И обещание, и тайм-аут являются асинхронными операциями, функция продолжает работать, пока она занята выполнением обещания и обработкой обратного вызова `setTimeout`. Это означает, что `Last line 1!` регистрируется первой, так как это не асинхронная операция. Поскольку стек вызовов еще не пуст, функция `setTimeout` и обещание в `funcOne` еще не могут быть добавлены в стек вызовов. В `funcTwo` переменная `res` получает `Promise`, потому что `Promise.resolve(Promise.resolve('Promise'))` эквивалентно `Promise.resolve('Promise')`, так как разрешение обещания просто разрешает его стоимость. `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!` и удаляется из стека.
#### Ответ: 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`
#### Ответ: C C помощью Proxy мы можем добавить собственное поведению объекту, которое мы передаем вторым аргументом. В нашем случае мы передаем объект `handler` который содержит свойства: `set` и `get`. `set` вызывается каждый раз когда мы _устанавливаем_ значения свойств, `get` же вызывается всякий раз когда мы _получаем_ значения свойств. Первый аргумент — пустой объект `{}`, который является значением `person`. Для него будет добавлено собственное поведение, описанное в объекте `handler`. При добавлении значения для объекта `person` будет вызвано свойство `set`. При запросе к значению `person` вызовется свойство `get`. Сначала мы устанавливаем новое свойство `name` для объекта Proxy (`person.name = "Lydia"`). Вызывается `set` и в лог попадает `"Added a new property!"`. Затем мы обращаемся к значению Proxy-объекта. Вызывается свойство `get` объекта `handler`. `"Accessed a property!"` попадает в лог.
#### Ответ: A С помощью `Object.seal` мы можем предотвращать как _добавление_ новых свойств, так и _удаление_ существующих. Однако, изменение существующих свойств остаётся доступным.
#### Ответ: C С помощью метода `Object.freeze` мы можем _заморозить_ объект. Свойства не могут быть добавлены, изменены или удалены. Однако, это _неглубоко_ замораживает объект. Замораживаются только _непосредственные_ свойства объекта. Если свойством является другой объект(в нашем примере `address`), свойства этого объекта не замораживаются и могут быть изменены.
#### Ответ: A Во-первых, мы вызваем `myFunc()` без передачи каких-либо аргументов. Поскольку мы не передаем аргументы, `num` и `value` получают свои значения по умолчанию: `num` равно `2`, а `value` возвращаемое значение функции `add`. В функцию `add` мы передаем в качестве аргумента `num` со значением `2`. `add` возвращает `4`, что является значением `value`. Затем мы вызваем `myFunc(3)` и передаем значение `3` в качестве значения аргумента `num`. Мы не передаем аргумент для `value`. Поскольку мы не передаем значение для аргумента `value`, он получаеи значение по умолчанию: возвращаемое значение функции `add`. В `add` мы передаем `num`, значение которого равно `3`. `add` возвращает `6`, что является значением `value`.
#### Ответ: D В ES2020 мы можем добавлять приватные переменные в классы с помощью символа `#`. Мы не можем получить доступ к этим переменным вне класса. Когда мы пытаемся записать `counter.#number`, выдается `SyntaxError`: мы не можем получить доступ вне класса `Counter`!
#### Ответ: B Чтобы выполнить итерацию по `members` в каждом элементе массива `teams`, нам нужно передать `teams[i].members` в функцию генератора `getMembers`. Функция генератора возвращает объект генератора. Чтобы перебрать каждый элемент в этом объекте-генераторе, нам нужно использовать `yield*`. Если бы мы написали `yield`, `return yield` или `return`, вся функция генератора была бы возвращена при первом вызове метода `next`.
#### Ответ: C Функция `addHobby` получает два аргумента, `hobby` и `hobbies`, со значением по умолчанию массива `hobbies` в объекте `person`. Во-первых, мы вызываем функцию `addHobby` и передаем `"running"` в качестве значения для `hobby`, а пустой массив в качестве значения для `hobbies`. Так как мы передаем пустой массив в качестве значения для `hobbies`, `"running"` добавляется к этому пустому массиву. Затем мы вызываем функцию `addHobby` и передаем `dancing` в качестве значения для `hobby`. Мы не передавали значение для `hobbies`, поэтому оно получает значение по умолчанию, свойство `hobbies` объекта `person`. Мы помещаем хобби `dancing` в массив `person.hobbies`. Наконец, мы вызываем функцию `addHobby` и передаем `"baking"` в качестве значения для `hobby`, а массив `person.hobbies` в качестве значения для `hobbies`. Мы помещаем хобби `baking` в массив `person.hobbies`. После нажатия `танцы` и `выпечка`, значение `person.hobbies` равно `["coding", "dancing", "baking"]`
#### Ответ: B Мы создаем переменную `pet`, которая является экземпляром класса `Flamingo`. Когда мы создаем этот экземпляр, вызывается `constructor` для `Flamingo`. Сначала регистрируется `"I'm pink. 🌸"`, после чего мы вызываем `super()`. `super()` вызывает конструктор родительского класса `Bird`. Конструктор в `Bird` вызывается и регистрирует `"I'm a bird. 🦢"`.
#### Ответ: D Ключевое слово `const` просто означает, что мы не можем _повторно объявить_ значение этой переменной, оно доступно только для чтения. Однако само значение не является неизменным. Свойства массива `emojis` можно изменить, например, добавив новые значения, объединив их или установив длину массива на 0.
#### Ответ: C По умолчанию объекты не являются итерируемыми. Итерируемым объект становится, если присутствует протокол итератора. Мы можем добавить это вручную, добавив символ итератора `[Symbol.iterator]`, который должен возвращать объект-генератор, например, сделав его функцией-генератором `*[Symbol.iterator]() {}`. Эта функция-генератор должна возвращать `Object.values` объекта `person`, если мы хотим, чтобы он возвращал массив `["Lydia Hallie", 21]`: `yield* Object.values(this)`.
#### Ответ: C Условие `if` внутри цикла `forEach` проверяет, является ли значение `num` истинным или ложным. Поскольку первое число в массиве `nums` равно `0`, то есть ложное значение, блок оператора `if` не будет выполнен. `count` увеличивается только для остальных 3 чисел в массиве `nums`: `1`, `2` и `3`. Поскольку `count` увеличивается на 1 3 раза, значение `count` равно `3`.
#### Ответ: D `?` позволяет нам дополнительно получить доступ к более глубоким вложенным свойствам внутри объектов. Мы пытаемся зарегистрировать элемент с индексом `1` в подмассиве с индексом `1` массива `fruits`. Если подмассив с индексом `1` в массиве `fruits` не существует, он просто вернет `undefined`. Если подмассив с индексом `1` в массиве `fruits` существует, но в этом подмассиве нет элемента с индексом `1`, он также вернет значение `undefined`. Во-первых, мы пытаемся зарегистрировать второй элемент в `['🍍']` подмассива `[['🍊', '🍌'], ['🍍']]`. Этот подмассив содержит только один элемент, что означает, что в индексе `1` нет элемента, и возвращает значение `undefined`. Затем мы вызываем функцию `getFruits` без передачи значения в качестве аргумента, что означает, что `fruits` по умолчанию имеет значение `undefined`. Поскольку мы условно связываем элемент с индексом `1` массива `fruits`, он возвращает значение `undefined`, поскольку этот элемент с индексом `1` не существует. Наконец, мы попытаемся зарегистрировать второй элемент в `['🍊', '🍌']` подмассива `['🍍'], ['🍊', '🍌']`. Элемент с индексом `1` в этом подмассиве — `🍌`, который регистрируется.
#### Ответ: A Мы устанавливаем переменную `calc` равной новому экземпляру класса `Calc`. Затем мы создаем экземпляр нового экземпляра `Calc` и вызываем метод увеличения для этого экземпляра. Поскольку свойство `count` находится в конструкторе класса `Calc`, свойство `count` не используется в прототипе `Calc`. Это означает, что значение `count` не было обновлено для экземпляра, на который указывает `calc`, `count` по-прежнему равен `0`.
#### Ответ: B Функция `updateUser` обновляет значения свойств `email` и `password` у пользователя, если их значения переданы в функцию, после чего функция возвращает объект `user`. Возвращаемое значение функции `updateUser` — это объект `user`, что означает, что значение `updatedUser` является ссылкой на тот же объект `user`, на который указывает `user`. `updatedUser === user` равно `true`.
#### Ответ: C Во-первых, мы вызываем метод `slice` для массива фруктов. Метод `slice` не изменяет исходный массив, а возвращает значение, которое было вырезано из массива: банановый смайлик. Затем мы вызываем метод `splice` для массива фруктов. Метод `splice` изменяет исходный массив, что означает, что массив фруктов теперь состоит из `['🍊', '🍎']`. Наконец, мы вызываем метод `unshift` для массива `fruit`, который изменяет исходный массив, добавляя предоставленное значение, в данном случае `🍇`, в качестве первого элемента в массиве. Массив фруктов теперь состоит из `['🍇', '🍊', '🍎']`.
#### Ответ: B Ключи объекта преобразуются в строки. Поскольку значение `dog` является объектом, `animals[dog]` на самом деле означает, что мы создаем новое свойство под названием `"object Object"`, равное новому объекту. `animals["object Object"]` теперь равно `{ emoji: "🐶", name: "Mara"}`. `cat` также является объектом, что означает, что `animals[cat]` на самом деле означает, что мы перезаписываем значение `animals["object Object"]` новыми свойствами кота. Регистрация `animals[dog]`, или фактически `animals["object Object"]`, поскольку преобразование объекта `dog` в строку приводит к `"object Object"`, возвращает `{ emoji: "🐈", name: " Сара"}`.
#### Ответ: A Функция `updateEmail` представляет собой стрелочную функцию и не привязана к объекту пользователя. Это означает, что ключевое слово `this` не относится к объекту `user`, а в данном случае относится к глобальной области видимости. Значение `email` в объекте `user` не обновляется. При регистрации значения `user.email` возвращается исходное значение `my@email.com`.
#### Ответ: D Метод `Promise.all` выполняет переданные промисы параллельно. Если одно обещание не выполняется, метод `Promise.all` _отколняется_ со значением отклоненного обещания. В этом случае `promise3` отклонен со значением `"Third"`. Мы перехватываем отклоненное значение в цепочке методов `catch` при вызове `runPromises`, чтобы перехватывать любые ошибки внутри функции `runPromises`. Только `"Third"` регистрируется, так как `promise3` отклонено с этим значением.
#### Ответ: C Метод `fromEntries` превращает двумерный массив в объект. Первый элемент в каждом подмассиве будет ключом, а второй элемент в каждом подмассиве будет значением. В этом случае мы сопоставляем массив `keys`, который возвращает массив, первый элемент которого является элементом массива ключей текущего индекса, а второй элемент является элементом массива значений текущего индекса. Это создает массив подмассивов, содержащих правильные ключи и значения, что приводит к `{ name: "Lydia", age: 22 }`
#### Ответ: C Значением по умолчанию для `address` является пустой объект `{}`. Когда мы устанавливаем переменную `member` равной объекту, возвращаемому функцией `createMember`, мы не передаем значение для адреса, что означает, что значение адреса является пустым объектом по умолчанию `{}`. Пустой объект является истинным значением, что означает, что условие `address ? address : null` условно возвращает `true`. Значением адреса является пустой объект `{}`.
#### Ответ: B Условие в операторе `if` проверяет, равно ли значение `!typeof randomValue` "строке". Оператор `!` преобразует значение в логическое значение. Если значение истинно, возвращаемое значение будет "ложным", если значение ложным, возвращаемое значение будет "истинным". В этом случае возвращаемое значение `typeof randomValue` является истинным значением `"number"`, что означает, что значение `!typeof randomValue` является логическим значением `false`. `!typeof randomValue === "string"` всегда возвращает `false`, поскольку на самом деле мы проверяем `false === "string"`. Поскольку условие вернуло `false`, запускается блок кода оператора `else`, и в журнал заносится сообщение `Yay it's a string!`.