Пожалуйста переверните

70 вопросов собеседования JavaScript.

Часть 4.

#translate#javascript

Оригинал статьи 70 JavaScript Interview Questions

31. Что такое функциональное программирование и какие особенности JavaScript позволяют считать его функциональным языком?

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

Методы массивов JavaScript map, filter и reduce являются самыми известными функциями в функциональном программировании из-за своей полезности и потому, что они не меняют массивы. Это делает эти функции чистыми. Также, в JavaScript есть замыкания и функции высшего порядка, что является признаком функционального языка.

  • Метод map создает новый массив с результатами высова callback функции на каждом элементе массива.
const words = ["Functional", "Procedural", "Object-Oriented"]

const wordsLength = words.map(word => word.length)
  • Метод filter создает новый массив, со всеми элементами, удавлетворяющими проверку в callback функции.
const data = [
  { name: "Mark", isRegistered: true },
  { name: "Mary", isRegistered: false },
  { name: "Mae", isRegistered: true },
]

const registeredUsers = data.filter(user => user.isRegistered)
  • Метод reduce применяет функцию к аккумулятору и к каждому элементу массива (слева направо), пока не уменьшит результат до одного значения.
const strs = ["I", " ", "am", " ", "Iron", " ", "Man"]
const result = strs.reduce((acc, currentStr) => acc + currentStr, "")

32. Что такое функции высшего порядка (Higher Order Functions)?

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

function higherOrderFunction(param, callback) {
  return callback(param)
}

33. Почему функции считаются объектами первого класса (First-class Objects)?

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

34. Собственная реализация метода Array.prototype.map.

function map(arr, mapCallback) {
  // Сперва мы проверяем правильность переданных аргументов
  if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== "function") {
    return []
  } else {
    let result = []
    // Мы создаем массив result каждый раз, когда мы вызываем эту функцию
    // потому что мы не хотим менять оригинальный массив
    for (let i = 0, len = arr.length; i < len; i++) {
      result.push(mapCallback(arr[i], i, arr))
      // вносим результат выполнения mapCallback в массив 'result'
    }
    return result // возвращаем массив result
  }
}

Определение метода Array.prototype.map от MDN

Метод map создает новый массив с результатами вызова переданной функции на каждом элементе переданного массива.

35. Собственная реализация метода Array.prototype.filter.

function filter(arr, filterCallback) {
  // Сперва мы проверяем правильность переданных аргументов
  if (
    !Array.isArray(arr) ||
    !arr.length ||
    typeof filterCallback !== "function"
  ) {
    return []
  } else {
    let result = []
    // Мы создаем массив result каждый раз, когда мы вызываем эту функцию
    // потому что мы не хотим менять оригинальный массив
    for (let i = 0, len = arr.length; i < len; i++) {
      // проверяем возвращаемое функцие1 filterCallback значение на "правдивость"
      if (filterCallback(arr[i], i, arr)) {
        // вносим текущее значение в массив result, если оно "правдиво
        result.push(arr[i])
      }
    }
    return result // возвращаем массив result
  }
}

Определение метода Array.prototype.filter от MDN

Метод filter создает новый массив со всеми элементами, которые прошли проверку, выраженную в переданной функции.

36. Собственная реализация метода Array.prototype.reduce.

function reduce(arr, reduceCallback, initialValue) {
  // Сперва мы проверяем правильность переданных аргументов
  if (
    !Array.isArray(arr) ||
    !arr.length ||
    typeof reduceCallback !== "function"
  ) {
    return []
  } else {
    // если initialValue не был передан в функцию, мы должны использовать
    let hasInitialValue = initialValue !== undefined
    let value = hasInitialValue ? initialValue : arr[0]
    // первый элемент массива в качестве initialValue

    // затем мы начинаем цикл с индекса 1, если initialValue не был передан
    // или с 0, если initialValue был передан
    for (let i = hasInitialValue ? 0 : 1, len = arr.length; i < len; i++) {
      // Затем для каждой итерации мы присваиваем
      // результат ReduCallback к значению переменной
      value = reduceCallback(value, arr[i], i, arr)
    }
    return value
  }
}

Определение метода Array.prototype.reduce от MDN

Метод reduce выполняет функцию reduce для каждого элемента массива, в результате чего на выходе получается одно значение.

37. Что такое агументы объекта?

Объект arguments представляет собой набор значение параметров, переданных в функцию. Это объект похож на массив - у него есть длина и мы можем получить доступ к его элементам, обратившись к их индексам. Но у него нет встроенных методов массива forEach, reduce, filter и map. Этот объект полезен, когда нужно узнать количество аргументов, переданных в функцию.

Мы можем конвертировать объект arguments в массив при помощи метода Array.prototype.slice.

function one() {
  return Array.prototype.slice.call(arguments)
}

Примечание: объект arguments не работает в стрелочных функциях ES6

function one() {
  return arguments
}
const two = function() {
  return arguments
}
const three = function three() {
  return arguments
}

const four = () => arguments

four() // Вызовет ошибку  - arguments is not defined

При вызове функции four появляется ошибка ReferenceError: arguments is not defined. Мы можем решить эту проблему использование оператора rest (если ваше окружение позволит).

const four = (...args) => args

Это автоматически помещает все значения параметров в массив.

38. Как создать объекты без прототипа?

Мы можем создать объект без прототипа используя метод Object create.

const o1 = {}
console.log(o1.toString())
// выведет [object Object] получив этот метод из Object.prototype

const o2 = Object.create(null)
// первым параметром является прототип объекта "o2", который в этом случае
//  будет нулевым, указывая, что мы не хотим никакого прототипа
console.log(o2.toString())
// выдаст ошибку o2.toString is not a function

39. Что коде ниже делает b глобальной переменной при вызове функции ?

function myFunc() {
  // let a = b = 0;
}

myFunc()

b становится глобальной переменной из-за того, что оператор присвоения = имеет ассоциативность справа-налево. Это означает, что когда несколько операторов присваивания появляются в одном выражении, они присваиваются справа налево. Таким образом, наш код становится таким.

function myFunc() {
  let a = (b = 0)
}

myFunc()

Сперва срабатывает присвоение b = 0, а b еще не была объевлена. И движок JS создает глобальную пременную и вовне функции. Затем он возвращает результат выражения b = 0, то есть 0, и присваивает это значение локальной переменной a при помощи ключевого слова let.

Мы можем решить эту проблему объявлением переменным перед тем, как присвоить им значения.

function myFunc() {
  let a, b
  a = b = 0
}
myFunc()

40. Что такое ECMAScipt?

ECMAScipt является стандартом создания скриптовых языков. Это означает, что JavaScript следует за изменениями стардартов в спецификации ECMAScipt, поскольку он является образцом для JavaScript.

Предыдущая статья Часть 3

Следующая статья Часть 5