Разбор Luxoft JavaScript quiz
Maksym PohribniakСовсем недавно компания Luxoft проводила JS Quiz, ссылка на который висела на главной странице dou.ua. В котором можно было выиграть футболку или повербанк. К слову, я выиграл футболку, так как у меня было 13 правильных ответов (из 15 возможных). Не хватило одного балла для повербанка. (один вопрос я неправильно решил из-за невнимательности (№1), а второй спорный (№8)).
Так, как тест уже закончился и по ссылке висят ответы – я хочу разобрать некоторые вопросы из него:
Вопрос #5
Which of the results of the following won't have a number type?
Какой из следующих результатов не будет иметь числовой тип?
Варианты ответов:
a) 77 + '77'
Неявное преобразование в строку будет вызвано бинарным оператором +, кода один из операндов является строкой.
b) Number('Not a ')
Вернет NaN, а typeof NaN – number.
c) '11' * 1
Численное преобразование происходит в математических функциях и выражениях. Например, когда операция применяется не к числу как в нашем примере. (кроме +).
d) parseFloat(‘123.45’)
Может вернуть значение Infinity, NaN или число и все они типа число.
✅ Правильный ответ - а (77 + '77')
Вопрос #6
What is the length of the array?
Какова длина массива?
[...[...'...']]
Варианты ответов:
a) 1
b) 2
c) 3
Для лучшего понимания перепишем данный код на более читабельный:
const str = '...';
const innerArr = [...str];
// spread оператор на строке работает так же, как использование .split('').
// innerArr будет представлять собой следующий массив [".", ".", "."]
const outerArr = [...innerArr];
// используем spread syntax для создания нового массива на основе существующего
✅ Правильный ответ - c (3)
Вопрос #7
What will be the output?
Какой будет результат?
let x, { x: y = 1 } = { x };
console.log(y);
Варианты ответов:
a) undefined
b) 1
c) { x }
Для лучшего понимания перепишем данный код на более читабельный:
let x; // объявляем переменную х
let { x: y = 1 } = { "x": x };
// с помощью оператора деструктуризации достаем ключ х как переменную y из объекта { "x": undefined }
// с дефолтныйм значением 1
// так как х === undefined, проставляется дефолтное значение
console.log(y); // 1
✅ Правильный ответ - b (1)
Вопрос #9
It's time for chaining assignments on objects. What will be the output?
Какой будет результат кода?
let foo = { n: 1 };
let bar = foo;
foo.x = foo = { n: 2 };
console.log(foo.x);
console.log(foo);
console.log(bar);
К сожалению варианты ответов именно к этому вопросу я не записал потому будут мои:
а) undefined, { n: 2 }, { n: 1, x: { n: 2 } }
b) {n: 2}, {n: 2, x: {n: 2}}, {n: 1}
c) undefined, { n: 2 }, { n: 1, x: undefined }
Для правильного решения данного задания нам нужно понимать 2 вещи:
- объекты передаются по ссылке
let a = {test: 1};
let b = a; // b и a теперь ссылаются на одну и туже область памяти
a = 2; // a больше не ссылается на объект {test: 1}
console.log(b) // {test: 1} ссылается на объект который изначально был а
- операторы присваивания являются право-ассоциативными
a = b = 5; // a и b будут равны 5
Это происходит, потому что оператор присваивания возвращает тот результат, который присваивает. Сначала b становится равным 5, затем a принимает значение b.
Возвращаемся к нашему примеру:
let foo = { n: 1 }; // создали объект
let bar = foo; // передали ссылку на выше созданный объект
foo.x = foo = { n: 2 };
// так, как операторы присваивания являются право-ассоциативными
// исполнения правой части кода (foo = { n: 2 })
// переменная foo принимает ссылку на совершенно новый объект
// при этом левая часть (foo.x) все еще ссылается на старый объект { n: 1 }
// на который так же ссылается bar
// и в foo.x(bar) мы записываем результат выполнения (foo = { n: 2 }) – { n: 2 }
// после выполнения этой строки в foo у нас лежит новый объкт
// а в bar.x мы записали ссылку на новый foo
console.log(foo.x); // undefined
console.log(foo); // {n: 2}
console.log(bar); // {n: 1, x: {{n: 2}}}
✅ Правильный ответ - а) undefined, { n: 2 }, { n: 1, x: { n: 2 } }
Вопрос #10
One of the common questions about 'setTimeout.' What will be the output?
Типичный вопрос про таймауты. Какой будет результат кода?
for ( var i = 0 ; i < 3 ; i++) {
setTimeout(() => console.log(i));
}
Варианты ответов:
a) 1 2 3
b) 0 1 2
c) 3 3 3
Этот вопрос направлен на понимание таких механизмов JS, как замыкания, области видимости и функция setTimeout. И его ответ стыдно уже не знать так как его спрашивают везде и только ленивый не писал разбор на него.
Функция setTimeout создаёт функцию (замыкание), у которой есть доступ к внешней по области видимости и переменной i. Функция выполняется (aсинхронный setTimeout выполняется после того как выполнится весь синхронный код, то есть на момент выполнения функции в setTimeout цыкл уже завершил свою работу) и выводит значение i, которое, после окончания выполнения цикла равняется 3.
✅ Правильный ответ - c (3 3 3)
Вопрос #11
Let's continue with setInterval + Promise. What will be the output?
setInterval + Promise. Какой будет результат кода?
(() => {
console.log('START');
const interval = setInterval(() => {
console.log('setInterval');
clearInterval(interval);
}, 0);
Promise.resolve().then(() => console.log('promise'));
console.log('END');
})();
Варианты ответов:
a) START END promise setInterval
b) START setInterval promise END
c) START END setInterval promise
Разбор этого же вопроса я уже описывал более детально здесь.
✅ Правильный ответ - a) START END promise setInterval
Вопрос #12
Ok, and what we will get after running this code?
Какой будет результат кода?
((x, func = () => x) => {
var x;
var y = x;
x = 2
return [x, y, func()];
})(1);
Варианты ответов:
a) [2,1,2]
b) [2,1,1]
c) [2, undefined,1]
Мы вызываем анонимную функцию и сразу же ей передаем один аргумент 1.
Параметр x внутри анонимной функции будет единицей.
Функцию func мы не передаем, потому используется её значение по умолчанию.
В параметрах по умолчанию можно использовать значения предыдущих (расположенных левее в списке) параметров.
Переменная х доступна для видимости из функции func и тоже 1.
Далее мы объявляем переменную x c помощью var. Переменные var считаются объявленными с самого начала исполнения функции вне зависимости от того, в каком месте функции реально находятся их объявления (при условии, что они не находятся во вложенной функции). Поэтому в данном случае var x ничего не делает. х у нас остается 1. Далее мы копируем значение x в переменную y, а в следующей строке изменяем значение x (y при этом не меняется т. к. значение 2 – примитив).
И возвращаем мы массив элементов [x, y, func()], где:
x = 2;
y = 1;
func() = 1;
так как func замкнулся на значении x=1 при инициализации дефолтных параметров.
✅ Правильный ответ - b) [2,1,1]
Вопрос #13
And, for 'arguments,' what will we get here:
И что касается «аргументов», что мы получим здесь:
function func1(x, y) {
arguments[0] = y;
return x;
}
function func2(x, y) {
return [ arguments[1], func1(x, y)];
}
func2(1, 2);
Варианты ответов:
a) [1,2]
b) [2,1]
c) [2,2]
Аргументы будут ссылаться на последние значения объекта arguments, при считывании значений аргументов будут считаны последние данные из arguments, а при изменении значений формальных аргументов будет обновлен и объект arguments.
То есть запись arguments[0] = y; эквивалента записи x = y;
✅ Правильный ответ - c) [2, 2]
Вопрос #14
Now the arrow function. What will we get after running this code:
Теперь стрелочные функции. Что мы получим после запуска этого кода:
let f1 = () => {};
f1();
let f2 = () => {
this.a = 1;
};
new f2();
let f3 = () => arguments;
f3('a')
Варианты ответов:
a) {} TypeError ReferenceError
b) undefined { ‘a’: 1 } [‘a’]
c) undefined TypeError ReferenceError
Здесь нужно знать как работают стлелочные функции и их ограничения, они:
- не имееют собственного объекта arguments
- не могут быть использованы как конструктор и вызовут ошибку при использовании с new
- стрелочные функции не могут быть использованы как генераторы
Запись let f1 = () => {}; Всего лишь создает функцию с пустым телом, а не возвращает объект как может показаться (из-pа неявного return);
Чтобы вернулся объект нужна дополнительная магия в виде скобок:
let f1 = () => ({});
✅ Правильный ответ - c) undefined TypeError ReferenceError
Если вам показался полезным и интересным мой разбор с объяснениями, присылайте мне в личку тесты или вопросы интересующие вас.
По ним я сделаю еще один разбор.
Спасибо за внимание!