Вопросы по JavaScript. Версия 1
Каким будет вывод?
Вопрос № 1
function sayHi() {
console.log(name)
console.log(age)
var name = "John"
let age = 30
}
sayHi()
- A: John и undefined
- B: John и ошибка
- C: ошибка
- D: undefined и ошибка
Ответ
Правильный ответ: D
В функции sayHi
мы сначала определяем переменную name
с помощью ключевого слова var
. Это означает, что name
поднимается в начало функции. name
будет иметь значение undefined
до тех пор, пока выполнение кода не дойдет до строки, где ей присваивается значение John
. Мы еще не определили значение name
, когда пытаемся вывести ее значение в консоль, поэтому получаем undefined
. Переменные, объявленные с помощью ключевых слов let
и const
, также поднимаются в начало области видимости, но в отличие от переменных, объявленных с помощью var
, не инициализируются, т.е. такие переменные поднимаются без значения. Доступ к ним до инициализации невозможен. Это называется временной мертвой зоной
. Когда мы пытаемся обратиться к переменным до их определения, JavaScript
выбрасывает исключение ReferenceError
.
Вопрос № 2
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
- A: 0 1 2 и 0 1 2
- B: 0 1 2 и 3 3 3
- C: 3 3 3 и 0 1 2
- D: 3 3 3 и 3 3 3
Ответ
Правильный ответ: C
Из-за очереди событий в JavaScript
функция обратного вызова setTimeout
выполняется после освобождения стека вызовов. Так как переменная i
в первом цикле определяется с помощью ключевого слова var
, она является глобальной. В цикле мы каждый раз увеличиваем значение i
на 1
, используя оператор ++
. К моменту выполнения setTimeout
в первом примере значение i
равняется 3
. Во втором цикле переменная i
определяется с помощью ключевого слова let
. Такие переменные (а также переменные, объявленные с помощью ключевого слова const
) имеют блочную область видимости (блок - это код внутри фигурных скобок - {}
). На каждой итерации i
будет иметь новое значение, и это значение будет замкнуто в области видимости внутри цикла.
Вопрос № 3
const shape = {
radius: 10,
diameter() {
return this.radius * 2
},
perimeter: () => 2 * Math.PI * this.radius
}
console.log(shape.diameter())
console.log(shape.perimeter())
- A: 20 и 62.83185307179586
- B: 20 и NaN
- C: 20 и 63
- D: NaN и 63
Ответ
Правильный ответ: B
Обратите внимание, что diameter
- это обычная функция, а perimeter
- стрелочная. У стрелочных функций, в отличие от обычных, значение this
указывает на внешнее/лексическое окружение. Это значит, что при вызове метода perimeter
его this
указывает не на объект shape
, а на глобальный объект window
. У этого объекта нет свойства radius
, поэтому возвращается undefined
.
Вопрос № 4
console.log(+true)
console.log(!"John")
- A: 1 и false
- B: 0 и true
- C: false и NaN
- D: false и false
Ответ
Правильный ответ: A
Унарный плюс (+
) приводит операнд к числу. true
- это 1
, а false
- 0
. Строка John
- это истинное значение. Мы спрашиваем, является ли это значение ложным? Ответ: false
.
Вопрос № 5
let c = { greeting: "Hey!" }
let d
d = c
c.greeting = "Hello!"
console.log(d.greeting)
- A: Hello!
- B: Hey!
- C: undefined
- D: ошибка
Ответ
Правильный ответ: A
В JavaScript
все объекты являются "ссылочными" типами данных, т.е. значения объектов передаются по ссылкам. Сначала в переменной c
создается ссылка на объект. Затем мы указываем переменной d
ссылаться на тот же объект, на который ссылается c
. При изменении объекта меняются значения всех указывающих на него ссылок.
Вопрос № 6
let a = 3
let b = new Number(3)
let c = 3
console.log(a == b)
console.log(a === b)
console.log(b === c)
- A: true false true
- B: false false true
- C: true false false
- D: false true true
Ответ
Правильный ответ: C
new Number
- это встроенная функция-конструктор. И хотя она выглядит как число, это не настоящее число: у него имеется ряд дополнительных возможностей. На самом деле это объект. Оператор ==
(абстрактное/нестрогое равенство) разрешает преобразование типов данных, он проверяет равенство значений. Оба значения равны 3
, поэтому возвращается true
. При использовании оператора ===
(строговое равенство, оператор идентичности) должны совпадать не только значения, но и типы данных. В данном случае это не так: new Number()
- это не число, а объект. Поэтому два последних сравнения возвращают false
.
Вопрос № 7
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}
constructor({ newColor = "green" } = {}) {
this.newColor = newColor
}
}
const freddie = new Chameleon({ newColor: "pink" })
freddie.colorChange("orange")
- A: orange
- B: pink
- C: green
- D: ошибка
Ответ
Правильный ответ: D
Метод colorChange
является статическим. Такие методы не имеют доступа к экземплярам класса. Так как freddie
- это экземпляр, статический метод в нем не доступен. Поэтому выбрасывается исключение TypeError
.
Вопрос № 8
// обратите внимание: код выполняется в нестрогом режиме
let greeting
greetign = {} // опечатка!
console.log(greetign)
- A:
- B: ошибка
- C: undefined
- D: ""
Ответ
Правильный ответ: A
С помощью выражения greetign = {}
мы создаем новый глобальный пустой объект, который выводится в консоль. Когда мы вместо greeting
написали greetign
, интерпретатор выполнил global.greetign = {}
в Node.js
(или window.greetign = {}
в браузере). В строгом режиме ("use strict"
) будет выброшено исключение ReferenceError: greetign is not defined
.
Вопрос № 9
function bark() {
console.log("Woof!")
}
bark.animal = "dog"
console.log(bark.animal)
- A: dog
- B: ошибка
- C: undefined
- D: ""
Ответ
Правильный ответ: A
В JavaScript
такое возможно, т.к. функции в JS
- это тоже объекты. Точнее, функция — это специальный тип объекта, который можно вызывать (такой объект имеет внутренний слот callable
). Кроме того, функция — это объект со свойствами, вызывать которые нельзя, поскольку они не являются функциями.
Вопрос № 10
function Person(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
const person = new Person("John", "Smith")
Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`
}
console.log(person.getFullName())
- A: ошибка
- B: ""
- C: John Smith
- D: undefined undefined
Ответ
Правильный ответ: A
Нельзя добавлять свойства к конструктору как к обычному объекту. Если необходимо добавить свойство или метод всем экземплярам, то следует использовать прототипы. В данном случае выражение Person.prototype.getFullName = function () { return ${this.firstName} ${this.lastName} }
сделает метод getFullName
рабочим. В чем здесь преимущество? Предположим, что мы добавили этот метод к конструктору. Возможно, он нужен не каждому экземпляру класса Person
. Это приведет к лишнему расходованию памяти, т.к. все экземпляры будут иметь указанный метод. Напротив, если мы добавим данный метод к прототипу, у нас будет только одно место в памяти, к которому смогут обращаться все экземпляры. Такие методы называются совместными или распределенными (shared).
Вопрос № 11
function Person(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
const john = new Person("John", "Smith")
const jane = Person("Jane", "Air")
console.log(john)
console.log(jane)
- A:
Person {firstName: "John", lastName: "Smith"}
иundefined
- B:
Person {firstName: "John", lastName: "Smith"}
иPerson {firstName: "Jane", lastName: "Air"}
- C:
Person {firstName: "John", lastName: "Smith"}
и{}
- D:
Person {firstName: "Smith", lastName: "Smith"}
и ошибка
Ответ
Правильный ответ: A
Мы создаем объект jane
без помощи ключевого слова new
. Использование new
приводит к созданию нового объекта (экземпляра). Без new
создается глобальный объект. Мы указали, что this.firstName
равняется Jane
и this.lastName
равняется Air
. На самом деле, мы определили global.firstName = 'Jane'
и global.lastName = 'Air'
. Значением jane
является undefined
, поскольку мы ничего не возвращаем из функции Person
.
Вопрос № 12
function sum(a, b) {
return a + b
}
console.log(sum(1, "2"))
- A: NaN
- B: ошибка
- C: "12"
- D: 3
Ответ
Правильный ответ: C
JavaScript
- это динамически типизированный язык: мы не определяем тип данных при объявлении переменных (для этого был придуман TypeScript
). Значения переменных могут быть автоматически преобразованы из одного типа в другой без нашего участия. Это называется "неявным приведением типов". Приведение - это преобразование данных из одного типа в другой. В рассматриваемом примере JavaScript
конвертировал число 1
в строку, чтобы операция имела смысл и вернула хоть какое-то значение. При сложении числа (1
) и стр оки ("2"
) число преобразуется в строку. Мы можем объединять строки так: "Hello" + "World"
. Это называется конкатенацией строк. Таким образом, 1 + "2"
возвращает "12"
.
Вопрос № 13
let number = 0
console.log(number++)
console.log(++number)
console.log(number)
- A: 1 1 2
- B: 1 2 2
- C: 0 2 2
- D: 0 1 2
Ответ
Правильный ответ: C
Постфиксный оператор ++
:
- возвращает значение (
0
); - увеличивает (инкрементирует) значение (после чего значением переменной
number
становится1
). Префиксный оператор++
: - инкрементирует значение (теперь
number === 2
); - возвращает значение (
2
). Результат:0 2 2
.
Вопрос № 14
function getPersonInfo(one, two, three) {
console.log(one)
console.log(two)
console.log(three)
}
const person = "John"
const age = 30
getPersonInfo`${person} is ${age} years old`
- A: John 30 ["", " is ", " years old"]
- B: ["", " is ", " years old"] John 30
- C: John ["", " is ", " years old"] 30
- D: undefined
Ответ
Правильный ответ: B
При использовании тегированных шаблонных литералов (tagged template literals) первым значением, возвращаемым функцией, является массив строк. Прочими значениями являются значения, переданные функции в качестве аргументов.
Вопрос № 15
function checkAge(data) {
if (data === { age: 18 }) {
console.log("Ты взрослый!")
} else if (data == { age: 18 }) {
console.log("Ты по-прежнему взрослый.")
} else {
console.log("Хм... У тебя что, нет возраста?")
}
}
checkAge({ age: 18 })
- A: Ты взрослый!
- B: Ты по-прежнему взрослый.
- C: Хм... У тебя что, нет возраста?
- D: undefined
Ответ
Правильный ответ: C
В операциях сравнения примитивы сравниваются по значениям, а объекты - по ссылкам. JavaScript
проверяет, чтобы объекты указывали на одну и ту же область памяти. Сравниваемые объекты в рассматриваемом примере не такие: объект, переданный в качестве аргумента, указывает на другое место в памяти, нежели объекты, используемые в сравнениях. Поэтому выражения { age: 18 } === { age: 18 }
и { age: 18 } == { age: 18 }
возвращают false
.
Вопрос № 16
function getAge(...args) {
console.log(typeof args)
}
getAge(30)
- A: number
- B: array
- C: object
- D: NaN
Ответ
Правильный ответ: C
Оператор распространения или расширения (spread, ...
) возвращает массив с аргументами, переданными функции. Массив - это объект, поэтому выражение typeof args
возвращает object
.
Вопрос № 17
function getAge() {
"use strict"
age = 30
console.log(age)
}
getAge()
- A: 30
- B: undefined
- C: ошибка
- D: NaN
Ответ
Правильный ответ: C
"use strict"
, среди прочего, позволяет предотвратить случайное объявление глобальных переменных. Мы не объявляли переменную age
, поэтому (в строгом режиме) выбрасывается исключение ReferenceError
. В нестрогом режиме ошибки не возникнет, а переменная age
станет свойством глобального объекта window
.
Вопрос № 18
const sum = eval("10*10+5")
console.log(sum)
- A: 105
- B: "105"
- C: ошибка
- D: "10*10+5"
Ответ
Правильный ответ: A
Функция eval
выполняет код, переданный ей в виде строки. Если это выражение (как в данном случае), то оно вычисляется (оценивается). Выражение 10 * 10 + 5
возвращает число 105
. Использовать eval
не рекомендуется по причинам безопасности.
Вопрос № 19
var num = 8
var num = 10
console.log(num)
- A: 8
- B: 10
- C: undefined
- D: ошибка
Ответ
Правильный ответ: B
С помощью ключевого сло ва var
можно определять любое количество одноименных переменных. Переменная будет хранить последнее присвоенное ей значение. Однако, такой трюк нельзя проделать с let
и const
, т.к. переменные, объявленные с помощью этих ключевых слов, имеют блочную область видимости.
Вопрос № 20
const obj = { 1: "a", 2: "b", 3: "c" }
const set = new Set([1, 2, 3, 4, 5])
console.log(obj.hasOwnProperty("1"))
console.log(obj.hasOwnProperty(1))
console.log(set.has("1"))
console.log(set.has(1))
- A: false true false true
- B: false true true true
- C: true true false true
- D: true true true true
Ответ
Правильный ответ: C
Ключи объектов (кроме Symbol
) являются строками, даже если заданы не в виде строк (например, индексы в массиве). Поэтому выражение obj.hasOwnProperty('1')
также возвращает true
. Однако, это не работает с Set
. Значение 1
отсутствует в set
: set.has('1')
возвращает false
, а set.has(1)
- true
.
Вопрос № 21
const obj = { a: "one", b: "two", a: "three" }
console.log(obj)
- A:
{ a: "one", b: "two" }
- B:
{ b: "two", a: "three" }
- C:
{ a: "three", b: "two" }
- D: ошибка
Ответ
Правильный ответ: C
Если в объекте имеется два ключа с одинаковыми именами, то первый ключ перезаписывается. Его позиция сохраняется, а значением становится последнее из присвоенных.
Вопрос № 22
for (let i = 1; i < 5; i++) {
if (i === 3) continue
console.log(i)
}
- A: 1 2
- B: 1 2 3
- C: 1 2 4
- D: 1 3 4
Ответ
Правильный ответ: C
Оператор continue
пропускает текущую итерацию (цикл), если условие удовлетворяется (является истинным).
Вопрос № 23
String.prototype.giveMePizza = () => {
return "Give me pizza!"
}
const name = "John"
console.log(name.giveMePizza())
- A: Give me pizza!
- B: ошибка
- C: ""
- D: undefined
Ответ
Правильный ответ: A
String
- это встроенный конструктор, к которому можно добавлять новые свойства. Мы добавили метод giveMePizza
к его прототипу. Строки-примитивы автоматически конвертируются (преобразуются) в строки-объекты (благодаря объектной обертке). Поэтому все строки (объекты) имеют доступ к указанному методу.
Вопрос № 24
const a = {}
const b = { key: "b" }
const c = { key: "c" }
a[b] = 123
a[c] = 456
console.log(a[b])
- A: 123
- B: 456
- C: undefined
- D: ошибка
Ответ
Правильный ответ: B
Ключи объекта (кроме Symbol
) автоматически преобразуются в строки (даже индексы в массиве). Мы пытаемся добавить объект в качестве ключа со значением 123
к объекту a
. Однако, когда мы приводим объект к строке, он превращается в [object Object]
. Таким образом, мы говорим, что a["object Object"] = 123
. Затем мы повторяем процедуру. c
- это другой объект, который мы также неявно приводим к строке. Поэтому a["object Object"] = 456
. Наконец, когда мы выводим a[b]
в консоль, мы на самом деле обращаемся к a["object Object"]
. Поэтому в консоль выводится 456
.
Вопрос № 25
const foo = () => console.log("first")
const bar = () => setTimeout(() => console.log("second"))
const baz = () => console.log("third")
bar()
foo()
baz()
- A: first second third
- B: first third second
- C: second first third
- D: second third first
Ответ
Правильный ответ: B
Сначала мы вызываем функцию setTimeout
. Однако, ее колбек выполняется последним. Это происходит из-за того, что в браузерах у нас имеется не только движок для запуска (выполнения) кода, но и WebAPI
. WebAPI
предоставляет нам setTimeout
и много других возможностей, например, DOM
. После того, как setTimeout
отправляется в WebAPI
, функция bar
удаляется из стека вызовов (call stack). После этого вызывается функция foo
, и first
выводится в консоль. foo
удаляется из стека и вызывается функция baz
. third
выводится в консоль. WebAPI
отправляет функцию обратного вызова setTimeout
в очередь событий (task queue, второе слово читается как "кью"). Цикл событий (event loop) проверяет стек вызовов и очередь задач. Если стек оказывается пустым, то в него помещается первый элемент из очереди. Вызывается функция bar
и в консоль выводится second
.
Вопрос № 26
<div onclick="console.log('div')">
<p onclick="console.log('p')">
Нажми меня!
</p>
</div>
- A: p div
- B: div p
- C: p
- D: div
Ответ
Правильный ответ: A
После клика по элементу p
в консоль будет выведено p
и div
. Поток события (распространение события) имеет три фазы: захват, цель и всплытие. По умолчанию обработчики событий выполняются на фазе всплытия (если не установлен параметр useCapture
со значением true
). Всплытие происходит от самого глубоко вложенного элемента до самого внешнего.
Вопрос № 27
const person = { name: "John" }
function sayHi(age) {
console.log(`${this.name} is ${age}`)
}
sayHi.call(person, 30)
sayHi.bind(person, 30)
- A: undefined is 30 и John is 30
- B: function и function
- C: John is 30 и John is 30
- D: John is 30 и function
Ответ
Правильный ответ: D
В обоих случаях мы передаем объект, на который будет указывать this
. Но метод call
выполняется сразу, а метод bind
возвращает копию функции с привязанным контекстом. Эту функцию следует вызывать отдельно или можно сделать так: sayHi.bind(person, 30)()
.
Вопрос № 28
function sayHi() {
return (() => 0)()
}
console.log(typeof sayHi())
- A: object
- B: number
- C: function
- D: undefined
Ответ
Правильный ответ: B
Функция sayHi
возвращает значение немедленно вызываемого функционального выражения (Immediately Invoked Function Expression, IIFE). Результатом является число 0
типа number
. Для информации: в JavaScript
имеется 8
встрое нных типов данных: string, number, bigint, boolean, null, undefined, object и symbol
. function
не является отдельным типом, функции - это объекты.
Вопрос № 29
console.log(typeof typeof 1)
- A: number
- B: string
- C: object
- D: undefined
Ответ
Правильный ответ: B
Выражение typeof 1
возвращает number
. Выражение typeof number
возвращает string
.
Вопрос № 30
const numbers = [1, 2, 3]
numbers[10] = 11
console.log(numbers)
- A: [1, 2, 3, 7 x null, 11]
- B: [1, 2, 3, 11]
- C: [1, 2, 3, 7 x empty, 11]
- D: ошибка
Ответ
Правильный ответ: C
Когда в массив добавляется значение, которое выходит за пределы длины массива, JavaScript
создает "пустые ячейки". На самом деле они имеют значение undefined
, но в консоль выводятся как [1, 2, 3, 7 x empty, 11]
(зависит от среды выполнения кода, от браузера).
Вопрос № 31
(() => {
let x, y
try {
throw new Error()
} catch (x) {
(x = 1), (y = 2)
console.log(x)
}
console.log(x)
console.log(y)
})()
- A: 1 undefined 2
- B: undefined undefined undefined
- C: 1 1 2
- D: 1 undefined undefined
Ответ
Правильный ответ: A
Блок catch
принимает параметр x
. Это не тот x
, который объявлен перед блоком try
. Мы присваиваем этому аргументу значение 1
, а переменной y
- 2
. После этого мы выводим в консоль значение x
, т.е. 1
. За пределами catch x
все еще имеет значение undefined
, а y
- 2
. Когда мы вызываем console.log(x)
за пределами catch
, возвращается undefined
, а console.log(y)
возвращает 2
.
Вопрос № 32
const result =
[[0, 1], [2, 3]].reduce(
(acc, cur) => {
return acc.concat(cur)
},
[1, 2]
)
console.log(result)
- A: [0, 1, 2, 3, 1, 2]
- B: [6, 1, 2]
- C: [1, 2, 0, 1, 2, 3]
- D: [1, 2, 6]
Ответ
Правильный ответ: C
[1, 2]
- начальное значение переменной acc
. После первого прохода acc
равняется [1, 2]
, а cur
- [0, 1]
. После конкатенации (объединения) acc
равняется [1, 2, 0, 1]
, а cur
- [2, 3]
. После их объединения, мы получаем [1, 2, 0, 1, 2, 3]
.
Вопрос № 33
console.log(!!null)
console.log(!!"")
console.log(!!1)
- A: false true false
- B: false false true
- C: false true true
- D: true true false
Ответ
Правильный ответ: B
null
- это false
. !null
возвращает true
. !true
возвращает false
.
""
- это false
. !""
возвращает true
. !true
возвращает false
.
1
- это true
. !1
возвращает false
. !false
возвращает true
.
Вопрос № 34
console.log([..."John"])
- A: ["J", "o", "h", "n"]
- B: ["John"]
- C: [[], "John"]
- D: [["J", "o", "h", "n"]]
Ответ
Правильный ответ: A
Строка является итерируемой (перебираемой) сущностью. Оператор распространения или расширения (spread, ...
) преобразует строку в массив, состоящий из символов этой строки.
Вопрос № 35
function* generator(i) {
yield i
yield i * 2
}
const gen = generator(10)
console.log(gen.next().value)
console.log(gen.next().value)
- A: [0, 10] и [10, 20]
- B: 20 и 20
- C: 10 и 20
- D: 0, 10 и 10, 20
Ответ
Правильный ответ: C
Выполнение обычных функций не может быть остановлено после их запуска. Однако, генераторы можно останавливать в процессе выполнения, а затем продолжать с места остановки. Каждый раз, когда в функции-генераторе встречается ключевое слово yield
, функция возвращает значение, указанное после него. Обратите внимание, что в генераторе вместо return
используется yield
. Сначала мы инициализируем генератор с i
равным 10
. Мы вызываем генератор, используя метод next
. Когда мы в первый раз вызываем генератор, i
равняется 10
. Движок JavaScript
встречает первое ключевое слово yield
и возвращает значение i
. После этого выполнение функции приостанавливается и 10
выводится в консоль. Затем мы снова вызываем функцию посредством next()
. Она запускается с того места, где остановилась, с i
равным 10
. Движок встречает следующее ключевое слово yield
и возвращает i * 2
. i
равно 10
, поэтому возвращается 20
.
Вопрос № 36
const firstPromise = new Promise((res, rej) => {
setTimeout(res, 500, "one")
})
const secondPromise = new Promise((res, rej) => {
setTimeout(res, 100, "two")
})
Promise.race([firstPromise, secondPromise]).then(res => console.log(res))
- A: one
- B: two
- C: two one
- D: one two
Ответ
Правильный ответ: B
Когда мы передаем несколько промисов методу race
, он возвращает первый разрешенный (выполненный или отклоненный) промис. В функцию setTimeout
мы передаем задержку в 500
мс для первого промиса и в 100
мс - для второго. Это означает, что secondPromise
разрешается первым со значением two
. Переменная res
имеет значение two
, которое и выводится в консоль.
Вопрос № 37
let person = { name: "John" }
const members = [person]
person = null
console.log(members)
- A:
null
- B:
[null]
- C:
[{}]
- D:
[{ name: "John" }]
Ответ
Правильный ответ: D
Сначала мы объявляем переменную person
со значением объекта, содержащего свойство name
. Затем мы объявляем переменную members
. Мы делаем первый элемент этого массива равным [person]
. Объекты взаимодействуют посредством ссылок при установке их равными друг другу. Когда мы назначаем ссылку из одной переменной в другую, создается копия этой ссылки (обратите внимание, что у этих переменных не одинаковые ссылки). Затем мы присваиваем переменной person
значение null
. Мы изменили только значение person
, а не первый элемент массива, поскольку этот элемент имеет другую (скопированную) ссылку на объект. Первый элемент в members
по-прежнему содержит ссылку на исходный объект. Когда мы выводим в консоль массив members
, первый элемент этого массива содержит значение объекта, который и выводится в консоль.
Вопрос № 38
const person = {
name: "John",
age: 30
}
for (const item in person) {
console.log(item)
}
- A:
{ name: "John" }
и{ age: 30 }
- B:
name
иage
- C:
John
и30
- D:
["name", "John"]
и["age", 30]
Ответ
Правильный ответ: B
С помощью цикла for..in
мы перебираем ключи объекта, в данном случае name
и age
. Ключи объекта (кроме Symbol
) являются строками. В каждом цикле мы устанавливаем значение item
равным текущему ключу, по которому он перебирается. Сначала item
равен name
, и выводится в консоль. Затем item
равен age
, что также выводится в консоль.
Вопрос № 39
console.log(3 + 4 + "5")
- A: "345"
- B: "75"
- C: 12
- D: "12"
Ответ
Правильный ответ: B
Ассоциативность операторов - это порядок оценивания выражения движком JavaScript
, слева направо или справа налево. Это пр оисходит только в том случае, если все операторы имеют одинаковый приоритет. У нас есть только один тип оператора: +
. Ассоциативность - слева направо. 3 + 4
оценивается первым. Это приводит к числу 7
. 7 + "5"
приводит к "75"
из-за неявного приведения типов. JavaScript
преобразует число 7
в строку. Мы можем объединять (конкатенировать) две строки с помощью оператор +
. Выражение '7' + '5'
возвращает 75
.
Вопрос № 40
const num = parseInt("7*6", 10)
console.log(num)
- A: 42
- B: "42"
- C: 7
- D: NaN
Ответ
Правильный ответ: C
Функция parseInt
проверяет, являются ли символы в строке допустимыми с точки зрения используемой системы счисления (второй необязательный аргумент). Как только встречает ся недопустимый символ, синтаксический анализ строки прекращается и последующие символы игнорируются. *
является недопустимым числом. Поэтому parseInt
прекращает разбор строки и возвращает 7
.
Вопрос № 41
const result =
[1, 2, 3].map(num => {
if (typeof num === "number") return
return num * 2
})
console.log(result)
- A: []
- B: [null, null, null]
- C: [undefined, undefined, undefined]
- D: [ 3 x empty ]
Ответ
Правильный ответ: C
Метод map
возвращает новый массив с обработанными с помощью функции обратного вызова элементами исходного массива. В данном случае элементы исходного массива являются числами, поэтому условие if typeof num === 'number'
удовлетворяется. После этого выполнение функции останавливается, в новый массив попадает значение переменной num
, равное undefined
.
Вопрос № 42
function greeting() {
throw "Всем привет!"
}
function sayHi() {
try {
const data = greeting()
console.log("Работает!", data)
} catch (error) {
console.log("Ошибка: ", error)
}
}
sayHi()
- A: Работает! Всем привет!
- B: Ошибка: undefined
- C: ошибка
- D: Ошибка: Всем привет!
Ответ
Правильный ответ: D
С помощью оператора throw
мы можем создавать собственные ошибки. Другими словами, с помощью этого оператора мы можем генерировать пользовательские исключения. Исключением может быть строка, число, логическое значение или объект. В данном случае, исключением является строка Всем привет!
. С помощью оператора catch
мы можем указать, что делать, если в блоке try
возникла ошибка. Исключение - Всем привет!
. error
равняется этой строке. Это приводит к Ошибка: Всем привет!
.
Вопрос № 43
function Car() {
this.make = "Lamborghini"
return { make: "Maserati" }
}
const myCar = new Car()
console.log(myCar.make)
- A: Lamborghini
- B: Maserati
- C: ошибка
- D: undefined
Ответ
Правильный ответ: B
Когда возвращается свойство, его значение равняется возвращаемому значению, а не значению, установленному в функции-конструкторе. Мы возвращаем строку Maserati
, поэтому значением myCar.make
является Maserati
.
Вопрос № 44
(() => {
let x = (y = 10)
})()
console.log(typeof x)
console.log(typeof y)
- A: undefined и number
- B: number и number
- C: object и number
- D: number и undefined
Ответ
Правильный ответ: A
Выражение let x = y = 10
на самом деле является сокращением для y = 10; let x = y
. Когда мы устанавливаем y
равным 10
, мы фактически добавляем свойство y
к глобальному объекту (window
в браузере, global
в Node.js
). В браузере window.y
теперь равняется 10
. Затем мы объявляем переменную x
со значением y
. Переменные, объявленные с помощью ключевых слов let
и const
, имеют блочную область видимости, они доступны только в том блоке, в котором они объявлены. Таким блоком в данном случае является немедленно вызываемое функциональное выражение (Immediately Invoked Function Expression, IIFE). Когда мы используем оператор typeof
, операнд x
не определен: мы пытаемся получить доступ к x
вне блока его объявления. Это означает, что x
имеет значение undefined
. Переменные, которым не присвоено значение, по умолчанию имеют значение undefined
. Выражение console.log(typeof x)
возвращает undefined
. Однако, мы создали глобальную переменную y
, присвоив ей значение 10
. Это значение доступно в любом месте кода. y
определена и содержит значение типа number
. Поэтому выражение console.log(typeof y)
возвращает number
.
Вопрос № 45
class Dog {
constructor(name) {
this.name = name
}
}
Dog.prototype.bark = function() {
console.log(`Woof I am ${this.name}`)
}
const pet = new Dog("Rex")
pet.bark()
delete Dog.prototype.bark
pet.bark()
- A: "Woof I am Rex" и ""
- B: "Woof I am Rex" и "Woof I am Rex"
- C: "Woof I am Rex" и undefined
- D: "Woof I am Rex" и ошибка