5 вопросов по JavaScript на которые вы должны знать ответ

4838

5 вопросов по JavaScript на которые вы должны знать ответ

5 вопросов по JavaScript на которые вы должны знать ответ
5 вопросов по JavaScript на которые вы должны знать ответ

На собеседованиях часто любят задавать однотипные вопросы, ответы на которые уже давно выучены.

Сегодня же мы рассмотрим те вопросы, про которые вспоминают достаточно редко.

И так, начнём!

1. Чему равно foo.x ?

var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};

Этот вопрос задают в топ 3% компаний (Apple, Google, Facebook).

Главное на что здесь стоит обратить внимание, так это то, что foo на которую ссылается foo.x “устанавливается” перед тем как foo изменится. foo.x ссылается на старое значение foo.

See section 11.13.1 of the ES5 spec:

  • Let lref be the result of evaluating LeftHandSideExpression.
  • Let rref be the result of evaluating AssignmentExpression.

Это значит, что в старом foo появиться новое свойство x равное {n: 2} . А в новое foo запишется {n: 2} .

Значение старого foo находиться в bar:

// bar
{
  n: 1,
  x: {
    n: 2
  }
}

Так как при дальнейшем выводе foo.x наше foo ссылается на его новое значение, в котором отсутствует x , то соответственно foo.x будет не определенно — undefined .

Ответ: undefined

2. Напишите функцию сложения вида add(num1)(num2)..

Примечание: Количество слагаемых не ограничено

В оригинале это задача решается таким образом:

const add = (a) => {
  let sum = a;
  const func = (b) => {
    if (b) {
      sum += b;
      return func;
    } else {
      return sum;
    }
  };
  return func;
};add(2)(3)(); // 5;

Но потом вам ставят одно условие.

Убрать в конце лишние скобки

add(2)(3) // 5add(1)(2)(5) // 8...

Теперь задача усложнилась. А решение кроется в переопределении метода valueOf .

Ответ:

const add = (a) => {
  let sum = a;
  const func = (b) => {
    sum += b;
    return func;
  };
  func.valueOf = () => sum;return func;
};console.log(add(2)(3)); // 5;

Когда мы вызываем console.log , он ожидает увидеть String, если его там нет, то он попытается сделать из полученного значения String.

В примере выше после выполнения add(2)(3) возвращается function, которую console.log будет превращать в String, в ходе этих действий будет вызван метод valueOf для преобразования function к примитиву, а так мы переопределили данный метод, то он вернёт наше значение sum вместо стандартного.

Подробнее об этом тут.

Примечание:

Данный пример не работает со всеми console.

3. Что выведется в консоль ? Объясните почему.

var a={},
    b={key:'b'},
    c={key:'c'};

a[b]=123;
a[c]=456;

console.log(a[b]);

Ответ: 456

Что же происходит? Когда у объекта устанавливается новое свойство, то JavaScript неявно сделает stringify значения. В коде выше b и c являются объектами, следовательно они оба конвертируются в "[object Object]" (String). Так как stringify значения равны, то получается, что мы присваиваем новое значение одному и тому же свойству.

Равносильно, что написать:

var a={},
    b='object',
    c='object';

a[b]=123;
a[c]=456;

4. Напишите простую функцию, чтобы узнать равен ли один из входных параметров 3.

Тут делается упор на проверку знаний об arguments, но иногда заходят ещё дальше и просят рассказать каким образом работает Array.prototype.slice.call(arguments).

Ответ:

function isThreePassed(){
 const args = Array.prototype.slice.call(arguments);
 return args.indexOf(3) != -1;
}isThreePassed(1,2) //false
isThreePassed(9,3,4,9) //true

Как мы знаем, arguments не массив, а обычный объект, поэтому у него нет такого полезного метода как indexOf. Для этого используется Array.prototype.slice.call(arguments), который делает из argument — array.

Но всё же, как он работает ?

.call() и .apply() позволяют явно установить this в функции. И если передать argument как this, то slice будет работать с ним как с обычным массивом.

А вот интересный эксперимент:

const o = {
    '0': 'zero',
    '1': 'one'
};[].slice.call(o); // [];const oo = {
    '0': 'zero',
    '1': 'one',
    length: 2
};[].slice.call(oo); // ["zero", "one"];

5. Объедините два массива с вложенностью

Задачу можно решать различными способами. Обычно хотят узнать знает ли собеседуемый такой метод как reduce.

Идея заключается в том, чтобы обойти все элементы исходного массива и его “под массивов” с целью вернуть найденные значения в новый массив. Это происходит рекурсивно пока мы не дойдём до последнего элемента.

Так же с формированием нового массива нам помогает concat.

Ответ:

const flatten = (arr) => arr.reduce((flat, toFlatten) =>  flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten), []);

источник