Несколько каверзных вопросов на собеседовании по кодированию JS

Этап 3 (день 3)

1. Следующий рекурсивный код вызовет переполнение стека, если список массивов слишком велик. Как вы можете исправить это и при этом сохранить рекурсивный шаблон?

var list = readHugeList();
var nextListItem = function() {
    var item = list.pop();
    if (item) {
        // process the list item...
        nextListItem();
    }
};

Ответ:
Возможного переполнения стека можно избежать, изменив функцию nextListItemследующим образом:

var list = readHugeList();
var nextListItem = function() {
    var item = list.pop();
    if (item) {
        // process the list item...
        setTimeout( nextListItem, 0);
    }
};

Переполнение стека исключено, поскольку цикл обработки событий обрабатывает рекурсию, а не стек вызовов. При запуске nextListItem, если itemне равен нулю, функция тайм-аута (nextListItem) помещается в очередь событий, и функция завершается, тем самым оставляя стек вызовов чистым. Когда очередь событий запускает событие с истекшим временем ожидания, обрабатывается следующий элемент и устанавливается таймер для повторного вызова nextListItem. Соответственно, метод обрабатывается от начала до конца без прямого рекурсивного вызова, поэтому стек вызовов остается чистым вне зависимости от количества итераций.

2. Создайте функцию, которая при наличии элемента DOM на странице будет обращаться к самому элементу и всем его дочерним элементам (не только его непосредственным дочерним элементам). Для каждого посещенного элемента функция должна передать этот элемент предоставленной функции обратного вызова.

Аргументы функции должны быть:

i) элемент DOM

ii) функция обратного вызова (которая принимает элемент DOM в качестве аргумента)

Ответ:
Посещение всех элементов дерева (DOM) — это классическое применение алгоритма поиска в глубину. Вот пример решения:

function Traverse(p_element,p_callback) {
   p_callback(p_element);
   var list = p_element.children;
   for (var i = 0; i < list.length; i++) {
       Traverse(list[i],p_callback);  // recursive call
   }
}

3. Что выведет следующий код и почему?

var b = 1;
function outer(){
   	var b = 2
    function inner(){
        b++;
        var b = 3;
        console.log(b)
    }
    inner();
}
outer();

Ответ:
Вывод на консоль будет «3».

В примере есть три замыкания, каждое из которых имеет собственное объявление var b. Когда вызывается переменная, замыкания будут проверяться в порядке от локального к глобальному, пока не будет найден экземпляр. Поскольку внутреннеезамыкание имеет собственную переменную b, именно это и будет выводиться.

Кроме того, из-за подъема код во внутреннем коде будет интерпретироваться следующим образом:

function inner () {
    var b; // b is undefined
    b++; // b is NaN
    b = 3; // b is 3
    console.log(b); // output "3"
}

4. Что такое WeakMap в ES6?

Ответ:
WeakMap такой же, как Map, где он набор пар ключ/значение. Но в WeakMap ключи должны быть объектами, а значения могут быть произвольными. Ссылки на объекты в ключах удерживаются слабо, что означает, что они являются целью сборки мусора (GC), если больше нет другой ссылки на объект. WeakMapAPI аналогичен Map API.

Однако одно из отличий от объектов Map заключается в том, что ключи WeakMap не являются перечисляемыми. И нет никаких методов, дающих нам список ключей. Если бы они были, список зависел бы от состояния сборки мусора, вводя недетерминизм. Если мы хотим иметь список ключей, мы должны использовать Map.

5. Что такое Set?

Ответ:
Set
объекты – это наборы уникальных значений. Повторяющиеся значения игнорируются, так как коллекция должна содержать все уникальные значения. Значения могут быть примитивными типами или ссылками на объекты.

Кроме того, NaNи undefinedтакже могут храниться в Set. . NaN считается тем же, что и NaN(хотя NaN !== NaN).

6. Что такое генераторная функция?

Ответ:
Функции-генераторы — это новая функция в ES6, которая позволяет функции генерировать множество значений с течением времени, возвращая объект, который можно повторять, чтобы извлекать значения из функции по одному значению за раз. время.

Функция-генератор возвращает итерируемый объект при вызове. Он написан с использованием нового синтаксиса *, а также нового ключевого слова yield, введенного в ES6.

Каждый раз, когда вызывается yield, полученное значение становится следующим значением в последовательности. Кроме того, обратите внимание, что генераторы вычисляют полученные значения по требованию, что позволяет им эффективно представлять последовательности, вычисление которых требует больших затрат, или даже бесконечные последовательности.

7. Что такое WeakSet?

Ответ:
Объект WeakSet позволяет хранить слабо удерживаемые объекты в коллекции.

Объекты WeakSet представляют собой наборы объектов. Объект в WeakSet может встречаться только один раз; он уникален в коллекции WeakSet. Основные отличия от объекта Set:

  • В отличие от Set, WeakSet представляют собой наборы только объектов, а не произвольных значений. любого типа.
  • WeakSet является слабым: ссылки на объекты в коллекции хранятся слабо. Если нет другой ссылки на объект, хранящийся в WeakSet, они могут быть удалены сборщиком мусора. Это также означает, что в коллекции нет списка текущих объектов. WeakSets не перечислимы.

8. Что такое undefined x 1 в JavaScript?

Ответ:

var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];

Когда вы запустите приведенный выше код и наберете console.log(trees); в консоли разработчика Chrome вы получите
["красное дерево", "бухта", "кедр", undefined × 1, "клен"]. Когда вы запустите код в консоли браузера Firefox, вы получите [“красное дерево”, “залив”, “кедр”, undefined, “клен”]. Таким образом, понятно, что браузер Chrome имеет свой способ отображения неинициализированных индексов в массивах. Однако, если вы установите флажок trees[3] === undefined в обоих браузерах, вы получите вывод, аналогичный true.

Примечание. Помните, что вам не нужно проверять неинициализированный индекс массива в trees[3] === 'undefined × 1', так как это даст вам ошибка. ‘undefined × 1’ – это просто способ отображения неинициализированного индекса массива в Chrome.

9. Что такое подъем функций в JavaScript?

Ответ:
Выражение функции

var foo = function foo(){ 
 	return 12; 
};

В JavaScript переменные и функции поднимаются. Сначала возьмем функцию hoisting. По сути, интерпретатор JavaScript смотрит вперед, чтобы найти все объявления переменных, а затем поднимает их наверх функции, где они объявлены. Например:

foo(); // Here foo is still undefined 
var foo = function foo(){ 
 	return 12; 
};

За кулисами приведенный выше код выглядит так:

var foo = undefined;
    foo(); // Here foo is undefined 
 	   foo = function foo(){
 	      / Some code stuff
      }
var foo = undefined;
 	 foo = function foo(){
 	     / Some code stuff
    }
    foo(); // Now foo is defined here

10. Что такое оператор instanceof в JavaScript? Каким будет вывод кода ниже?

function foo(){ 
  return foo; 
}
new foo() instanceof foo;

Ответ:
Здесь оператор instanceof проверяет текущий объект и возвращает true, если объект имеет указанный тип.

Например:

var dog = new Animal();
dog instanceof Animal // Output : true

Здесь собака instanceof Animal имеет значение true, так как собаканаследуется от Animal.prototype.

var name = new String("xyz");
name instanceof String // Output : true

Здесь name instanceof String верно, так как nameнаследуется от String.prototype. Теперь давайте разберем код ниже:

function foo(){ 
  return foo; 
}
new foo() instanceof foo;

Здесь функция foo возвращает foo, что снова указывает на функцию foo.

function foo(){
  return foo; 
}
var bar = new foo();
// here bar is pointer to function foo(){return foo}.

Таким образом, new foo() instanceof foo возвращает false;

На сегодня все… Спасибо, что прочитали. Похлопайте, если вам понравилась эта статья. Приятного обучения :)

Ссылка на статью:

https://www.toptal.com/javascript/interview-questions

https://medium.com/@vigowebs/frequently-asked-es6-interview-questions-and-answers-e3fb7f2dba2

https://www.codementor.io/@nihantanu/21-essential-javascript-tech-interview-practice-questions-answers-du107p62z