Практикуйтесь в предсказании вывода JavaScript-кода: 111 вопросов из React Native Interview Handbook и 80 дополнительных. Начните готовиться прямо сейчас!
Прежде чем открыть ответ, точно сформулируйте вывод. Затем объясните правило, которое к нему приводит: порядок вычислений, область видимости, приведение типов, ссылочная идентичность, поиск по прототипу или планирование микрозадач. Запускайте сниппет только после того, как дали свой ответ.
111 проверенных вопросов.
1. Сравнение массивов через равенство ссылок?
Ответ: false, затем true. Каждый литерал массива создаёт отдельный объект; b указывает на тот же объект, что и a.
console.log([] === []);
const a = [];
const b = a;
console.log(a === b);2. Стрелочная функция и arguments?
Ответ: outer. Стрелочные функции не создают собственный объект arguments; они захватывают внешний.
function outer() {
const arrow = () => console.log(arguments[0]);
arrow('inner');
}
outer('outer');3. Возвращаемое значение async-функции?
Ответ: true, затем 42. Асинхронная функция всегда возвращает Promise, который выполняется с возвращаемым значением.
async function getValue() {
return 42;
}
console.log(getValue() instanceof Promise);
getValue().then(console.log);4. Базовый hoisting с var?
Ответ: undefined, затем 10. Объявление поднимается и инициализируется undefined; присваивание остаётся на месте.
console.log(a);
var a = 10;
console.log(a);5. Арифметика с булевыми значениями?
Ответ: 2, 1, 0. Численное преобразование отображает true в 1, false в 0.
console.log(true + true);
console.log(true + false);
console.log(Number(false));6. Порядок цепочки map и filter?
Ответ: [6, 8]. Сначала map создаёт [2, 4, 6, 8], затем filter оставляет значения больше 4.
const result = [1, 2, 3, 4]
.map(value => value * 2)
.filter(value => value > 4);
console.log(result);7. Изменение ключа сбрасывает состояние?
Ответ: Изменение userId сбрасывает локальное состояние Profile. Изменение key заставляет React рассматривать компонент как новый экземпляр.
<Profile key={userId} userId={userId} />;8. Temporal Dead Zone класса?
Ответ: ReferenceError. Объявления классов недоступны до момента вычисления объявления.
const user = new User();
class User {}9. Счётчик через замыкание?
Ответ: 1, 2. Возвращаемая функция сохраняет доступ к своему лексическому окружению.
function counter() {
let count = 0;
return () => ++count;
}
const next = counter();
console.log(next());
console.log(next());10. Замыкание с let в цикле?
Ответ: 0, 1, 2. let создаёт новую привязку для каждой итерации.
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}11. Замыкание с var в цикле?
Ответ: 3, 3, 3. Все колбэки замыкаются на одну и ту же переменную, область видимости которой — функция.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}12. Область видимости параметра по умолчанию?
Ответ: ReferenceError. Собственная неинициализированная привязка параметра затеняет внешнее значение в области выражения по умолчанию.
let value = 5;
function show(value = value) {
return value;
}
show();13. Сортировка по умолчанию лексикографическая?
Ответ: [1, 10, 2]. Без компаратора sort сравнивает строковые представления.
const values = [10, 2, 1];
values.sort();
console.log(values);14. Значения по умолчанию при деструктуризации и дырки?
Ответ: 10, null, 30. Значения по умолчанию применяются к undefined или отсутствующему элементу, но не к null.
const [a = 10, b = 20, c = 30] = [undefined, null];
console.log(a, b, c);15. Значения по умолчанию при деструктуризации?
Ответ: null, 20. Значение по умолчанию используется только когда свойство равно undefined.
const { a = 10, b = 20 } = { a: null, b: undefined };
console.log(a, b);16. Дублирующиеся объявления функций?
Ответ: 2. В одной области видимости позднее объявление функции заменяет раннее.
console.log(getValue());
function getValue() { return 1; }
function getValue() { return 2; }17. Порядок очистки эффекта?
Ответ: Для 0 к 1: effect 0, cleanup 0, effect 1. React очищает предыдущий эффект перед запуском замены.
useEffect(() => {
console.log('effect', count);
return () => console.log('cleanup', count);
}, [count]);18. Преобразования пустого массива?
Ответ: пустая строка, 0, true. Пустой массив преобразуется в пустую строку, которая затем преобразуется в ноль при численном сравнении.
console.log(String([]));
console.log(Number([]));
console.log([] == false);19. Пустой массив зависимостей и устаревшее замыкание?
Ответ: Он будет многократно выводить начальное значение count. Колбэк эффекта захватывает count из первого рендера.
useEffect(() => {
const id = setInterval(() => console.log(count), 1000);
return () => clearInterval(id);
}, []); // захватывает начальное значение count20. Цикл событий: Promise vs таймер?
Ответ: A, D, C, B. Сначала выполняется синхронный код, затем микрозадачи, затем задачи таймера.
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');21. FlatList и extraData?
Ответ: Строки могут не обновиться, когда изменяется только selectedId. FlatList ведёт себя как PureComponent и может пропустить работу, если его релевантные пропсы остаются поверхностно равными.
<FlatList
data={items}
renderItem={({ item }) => (
<Row item={item} selected={selectedId === item.id} />
)}
/>;22. Замыкание функции после return?
Ответ: 1, затем 2. inner сохраняет лексическое окружение завершённого вызова outer.
function outer() {
let value = 1;
return function inner() {
console.log(value++);
};
}
const next = outer();
next();
next();23. Объявление функции и присваивание var?
Ответ: function, затем number. Объявление функции инициализирует value первым; присваивание во время выполнения позже заменяет его на 10.
console.log(typeof value);
var value = 10;
function value() {}
console.log(typeof value);24. Hoisting объявления функции?
Ответ: Hello. Объявление функции поднимается вместе с её телом.
sayHello();
function sayHello() {
console.log('Hello');
}25. Hoisting функционального выражения?
Ответ: TypeError: sayHello is not a function. Поднимается только объявление var. Его значение undefined в момент вызова.
sayHello();
var sayHello = function() {
console.log('Hello');
};26. Свойство length функции?
Ответ: 3, 1, 0. length функции подсчитывает параметры до первого значения по умолчанию и исключает rest-параметр.
function first(a, b, c) {}
function second(a, b = 2, c) {}
function third(...args) {}
console.log(first.length, second.length, third.length);27. Функциональные обновления состояния?
Ответ: После одного нажатия count равен 3. React применяет каждый апдейтер к результату предыдущего поставленного в очередь апдейтера.
setCount(c => c + 1);
setCount(c => c + 1);
setCount(c => c + 1);28. Выполнение геттера?
Ответ: getter, затем React Native. Чтение свойства-аксессора выполняет его геттер-функцию.
const user = {
first: 'React',
last: 'Native',
get name() {
console.log('getter');
return `${this.first} ${this.last}`;
},
};
console.log(user.name);29. Тяжёлая работа JavaScript и UI?
Ответ: Приложение может зависнуть или пропускать кадры, пока цикл не завершится. Синхронная тяжёлая работа блокирует поток JavaScript и задерживает обработку событий и обновлений React.
const press = () => {
const result = expensiveSynchronousLoop();
setResult(result);
};30. Hoisting с var?
Ответ: undefined. Локальное объявление поднимается, но присваивание остаётся на своём месте.
var x = 21;
function test() {
console.log(x);
var x = 20;
}
test();31. Ленивый инициализатор состояния?
Ответ: Начальное значение вычисляется один раз при первом рендере. Функция-инициализатор вызывается только при первой инициализации.
const [state, setState] = useState(() => {
return computeInitialValue();
});Чтобы уверенно проходить собеседования, регулярно практикуйтесь в предсказании вывода кода. Возьмите за правило: сначала проговорите ответ, потом объясните механику, и только затем запускайте код. Так вы научитесь мыслить как интерпретатор JavaScript.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →