JavaScript — популярный язык программирования в Интернете. Высокоуровневый интерпретируемый язык программирования использует мультипарадигмальный подход. Таким образом, он имеет несколько черт функционального программирования, и такие компании, как Google и Facebook, используют JavaScript для создания сложных веб-приложений, подобных настольным.

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

Здесь мы составили список важных вопросов для собеседования по Javascript, которые помогут вам ответить на вопросы предстоящего собеседования по JS.

1. Что такое принуждение в JavaScript?

В JavaScript преобразование между двумя разными встроенными типами называется приведением. В JavaScript существует две формы принуждения: явное и неявное.

Вот пример явного принуждения:

var a = "48";
var b = Number( a );
a;                // "48"
b;                // 48 -- the number!

А вот пример неявного принуждения:

var a = "48";
var b = a * 1;    // "48" implicitly coerced to 42 here
a;                // "48"
b;                // 48 -- the number!

2. Объясните равенство в JavaScript.

JavaScript имеет как строгое сравнение, так и сравнение с преобразованием типов:

  • Строгое сравнение (например, ===) проверяет равенство значений, не допуская принуждения
  • Абстрактное сравнение (например, ==) проверяет равенство значений с разрешенным приведением
var a = "42";
var b = 42;
a == b;            // true
a === b;        // false

Несколько простых правил равенства:

  • Если какое-либо значение (также известное как сторона) в сравнении может быть значением true или false , избегайте == и используйте ===.
  • Если любое значение в сравнении может быть из этих конкретных значений (0, “” или [] — пустой массив), избегайте == и используйте ===.
  • Во всех остальных случаях вы можете безопасно использовать ==. Это не только безопасно, но и во многих случаях упрощает ваш код, повышая его читабельность.

3. Что такое оператор typeof?

· JavaScript предоставляет оператор typeof, который может проверять значение и сообщать вам его тип:

var a;
typeof a;                // "undefined"
a = "hello world";
typeof a;                // "string"
a = 42;
typeof a;                // "number"
a = true;
typeof a;                // "boolean"
a = null;
typeof a;                // "object" -- weird, bug
a = undefined;
typeof a;                // "undefined"
a = { b: "c" };
typeof a;                // "object"

4. Какой тип объекта?

Тип объекта относится к составному значению, в котором вы можете установить свойства (именованные расположения), каждое из которых содержит собственные значения любого типа.

var obj = {
  a: "hello world", // property
  b: 42,
  c: true
};
obj.a;        // "hello world", accessed with doted notation
obj.b;        // 42
obj.c;        // true
obj["a"];    // "hello world", accessed with bracket notation
obj["b"];    // 42
obj["c"];    // true

Обозначение скобок также полезно, если вы хотите получить доступ к свойству/ключу, но имя хранится в другой переменной, например:

var obj = {
 a: "hello world",
 b: 42
};
var b = "a";
obj[b];            // "hello world"
obj["b"];        // 42

5. Объяснение массивов в JavaScript

array — это объект, который содержит значения (любого типа) не только в именованных свойствах/ключах, но и в позициях с числовым индексом:

var arr = [
  "hello world",
  42,
  true
];
arr[0];            // "hello world"
arr[1];            // 42
arr[2];            // true
arr.length;        // 3
typeof arr;        // "object"

6. Объяснение значений и типов в JavaScript

В JavaScript есть типизированные значения, а не типизированные переменные. Доступны следующие встроенные типы:

  • string
  • number
  • boolean
  • null и undefined
  • object
  • symbol (новое для ES6)

7. Объясните Null и Undefined в JavaScript

JavaScript (и, соответственно, TypeScript) имеет два нижних типа: null и undefined. Они предназначены для разных целей:

  • Что-то не инициализировано: undefined.
  • Что-то сейчас недоступно: null.

8. Что такое строгий режим?

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

        // Non-strict code...
       (function(){
          "use strict";
           // Define your library strictly...
       })();
       // Non-strict code...

9. Что такое полифилл?

Полифилл — это, по сути, определенный код (или плагин), который позволит вам иметь некоторые определенные функции, которые вы ожидаете в текущих или «современных» браузерах, которые также будут работать в других браузерах, которые не имеют встроенной поддержки этой функции.

  • Полифиллы не являются частью стандарта HTML5.
  • Полифиллинг не ограничивается Javascript

10. Что такое ключевое слово let в JavaScript?

Помимо создания объявлений для переменных на уровне функций, ES6 позволяет вам объявлять переменные, принадлежащие отдельным блокам (пары { .. }), используя ключевое слово let .

11. Узнав, что несортированный массив содержит (n — 1) из n последовательных чисел (где границы определены), найдите пропущенное число за время O(n)

// The output of the function should be 8
var arrayOfIntegers = [2, 5, 1, 4, 9, 6, 3, 7];
var upperBound = 9;
var lowerBound = 1;
findMissingNumber(arrayOfIntegers, upperBound, lowerBound); // 8
function findMissingNumber(arrayOfIntegers, upperBound, lowerBound) {
// Iterate through array to find the sum of the numbers
var sumOfIntegers = 0;
for (var i = 0; i < arrayOfIntegers.length; i++) {
  sumOfIntegers += arrayOfIntegers[i];
}
// Find theoretical sum of the consecutive numbers using a variation of Gauss Sum.
// Formula: [(N * (N + 1)) / 2] - [(M * (M - 1)) / 2];
// N is the upper bound and M is the lower bound
upperLimitSum = (upperBound * (upperBound + 1)) / 2;
lowerLimitSum = (lowerBound * (lowerBound - 1)) / 2;
theoreticalSum = upperLimitSum - lowerLimitSum;
return theoreticalSum - sumOfIntegers;
}

12. Удалить дубликаты массива и вернуть массив только уникальных элементов

// ES6 Implementation
var array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
Array.from(new Set(array)); // [1, 2, 3, 5, 9, 8]
// ES5 Implementation
var array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
uniqueArray(array); // [1, 2, 3, 5, 9, 8]
function uniqueArray(array) {
  var hashmap = {};
  var unique = [];
for(var i = 0; i < array.length; i++) {
  // If key returns undefined (unique), it is evaluated as false.
  if(!hashmap.hasOwnProperty(array[i])) {
     hashmap[array[i]] = 1;
     unique.push(array[i]);
  }
}
return unique;
}

13. По заданной строке переверните каждое слово в предложении

Подробности:

Например, Welcome to this Javascript Guide! должно стать emocleW ot siht tpircsavaJ !ediuG

var string = "Welcome to this Javascript Guide!";
// Output becomes !ediuG tpircsavaJ siht ot emocleW
var reverseEntireSentence = reverseBySeparator(string, "");
// Output becomes emocleW ot siht tpircsavaJ !ediuG
var reverseEachWord = reverseBySeparator(reverseEntireSentence, " ");
function reverseBySeparator(string, separator) {
  return string.split(separator).reverse().join(separator);
}

14. Внедрите постановку в очередь и удаление из очереди, используя только два стека

Поставить в очередь означает добавить элемент, удалить из очереди, чтобы удалить элемент.

var inputStack = []; // First stack
var outputStack = []; // Second stack
// For enqueue, just push the item into the first stack
function enqueue(stackInput, item) {
  return stackInput.push(item);
}
function dequeue(stackInput, stackOutput) {
   // Reverse the stack such that the first element of the output stack is the
  // last element of the input stack. After that, pop the top of the output to
  // get the first element that was ever pushed into the input stack
if (stackOutput.length <= 0) {
  while(stackInput.length > 0) {
   var elementToOutput = stackInput.pop();
   stackOutput.push(elementToOutput);
  }
}
return stackOutput.pop();
}

15. Объясните всплывающие окна событий и как их можно предотвратить

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

Одним из способов предотвращения всплытия событий является использование event.stopPropagation() или event.cancelBubble в IE ‹ 9.

16. Как очистить массив в JavaScript?

Подробности:

var arrayList = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’];

Как мы можем очистить массив выше?

Способ 1

arrayList = [];

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

Например:

var arrayList = ['a', 'b', 'c', 'd', 'e', 'f']; // Created array
var anotherArrayList = arrayList;  // Referenced arrayList by another variable
arrayList = []; // Empty the array
console.log(anotherArrayList); // Output ['a', 'b', 'c', 'd', 'e', 'f']

Метод 2

arrayList.length = 0;

Приведенный выше код очистит существующий массив, установив его длину в 0. Этот способ очистки массива также обновит всю ссылочную переменную, указывающую на исходный массив. Этот способ очистки массива полезен, когда вы хотите обновить все другие ссылочные переменные, указывающие на arrayList.

Например:

var arrayList = ['a', 'b', 'c', 'd', 'e', 'f']; // Created array
var anotherArrayList = arrayList;  // Referenced arrayList by another variable
arrayList.length = 0; // Empty the array by setting length to 0
console.log(anotherArrayList); // Output []

Способ 3

arrayList.splice(0, arrayList.length);

Вышеупомянутая реализация также будет работать отлично. Этот способ очистки массива также обновит все ссылки исходного массива.

var arrayList = ['a', 'b', 'c', 'd', 'e', 'f']; // Created array
var anotherArrayList = arrayList;  // Referenced arrayList by another variable
arrayList.splice(0, arrayList.length); // Empty the array by setting length to 0
console.log(anotherArrayList); // Output []

Метод 4

while(arrayList.length) {
 arrayList.pop();
}

Вышеприведенная реализация также может очистить массив. Но не рекомендуется использовать часто.

17. Напишите функцию «mul», которая будет правильно вызываться, как показано ниже.

Подробности:

console.log(mul(2)(3)(4)); // вывод: 24

console.log(mul(4)(3)(4)); // вывод: 48

function mul (x) {
  return function (y) { // anonymous function
   return function (z) { // anonymous function
    return x * y * z;
    };
  };
}

Здесь функция mul принимает первый аргумент и возвращает анонимную функцию, которая принимает второй параметр, и возвращает анонимную функцию, которая принимает третий параметр и возвращает умножение аргументов, которые передаются последовательно.

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

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

18. Как проверить, является ли объект массивом или нет? Предоставьте код.

Лучший способ узнать, является ли объект экземпляром определенного класса или нет, используя toString метод из Object.prototype

var arrayList = [1 , 2, 3];

Один из лучших случаев использования проверки типов объекта — это перегрузка методов в JavaScript. Для понимания этого предположим, что у нас есть метод по имени приветствие, который принимает одну строку, а также список строк, поэтому, чтобы сделать наш метод приветствия работоспособным в обеих ситуациях, нам нужно знать, какой тип параметра передается, это одно значение или список. ценности?

function greet(param) {
  if() {
     // here have to check whether param is array or not
  }
  else {
       }
}

Однако в приведенной выше реализации может не потребоваться проверка типа для массива, мы можем проверить строку с одним значением и поместить логический код массива в блок else, давайте посмотрим ниже код для того же.

function greet(param) {
  if(typeof param === 'string') {
  }
  else {
       // If param is of type array then this block of code 
       would execute
       }     
}

· Теперь все в порядке, мы можем использовать две вышеприведенные реализации, но когда у нас возникает ситуация, когда параметр может быть типа single value, array и object, у нас будут проблемы.

· Возвращаясь к проверке типа объекта. Как мы уже упоминали, мы можем использовать Object.prototype.toString

if(Object.prototype.toString.call(arrayList) === '[object Array]') {
   console.log('Array!');
}

· Если вы используете jQuery, вы также можете использовать метод jQuery isArray:

if($.isArray(arrayList)) {
    console.log('Array');
} 
else {
 console.log('Not an array');
}

· К вашему сведению, jQuery использует Object.prototype.toString.call для внутренней проверки, является ли объект массивом или нет.

· В современном браузере вы также можете использовать:

Array.isArray(arrayList);

Array.isArray поддерживается Chrome 5, Firefox 4.0, IE 9, Opera 10.5 и Safari 5

19. Как бы вы использовали замыкание для создания частного счетчика?

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

function counter() {
var _counter = 0;
// return an object with several functions that allow you
// to modify the private _counter variable
return {
add: function(increment) { _counter += increment; },
retrieve: function() { return 'The counter is currently at: ' + _counter; 
}
 }
}
// error if we try to access the private variable like below
// _counter;
// usage of our counter function
var c = counter();
c.add(5);
c.add(9);
// now we can access the private variable in the following way
c.retrieve(); // => The counter is currently at: 14

20. Напишите функцию, которая позволит вам это сделать.

Подробности:

var addSix = createBase(6);

добавить шесть (10); // возвращает 16

добавить шесть (21); // возвращает 27

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

function createBase(baseNumber) {
  return function(N) {
    // we are referencing baseNumber here even though it 
       was declared
    // outside of this function. Closures allow us to do this 
       in JavaScript
    return baseNumber + N;
  }
}

21. Что делает оператор &&?

Оператор && или Логическое И находит первое ложное выражение в своих операндах и возвращает его, а если не находит никакого ложного выражения, возвращает последнее выражение. Он использует короткое замыкание, чтобы предотвратить ненужную работу. Я использовал это в блоке catch при закрытии соединения с базой данных в одном из моих проектов.

console.log(false && 1 && []); //logs false
console.log(" " && true && 5); //logs 5

Использование операторов if.

const router: Router = Router();
  router.get('/endpoint', (req: Request, res: Response) => {
     let conMobile: PoolConnection;
     try {
        //do some db operations
     } catch (e) {
     if (conMobile) {
      conMobile.release();
     }
  }
});

Использование оператора &&.

const router: Router = Router();
router.get('/endpoint', (req: Request, res: Response) => {
  let conMobile: PoolConnection;
  try {
     //do some db operations
  } catch (e) {
    conMobile && conMobile.release()
  }
});

22. Что делает оператор ||?

Оператор || или логическое ИЛИ находит первое истинное выражение в своих операндах и возвращает его. Это также использует короткое замыкание, чтобы предотвратить ненужную работу. Раньше он использовался для инициализации значений параметров по умолчанию в функциях до поддержки параметров функций по умолчанию ES6.

console.log(null || 1 || undefined); //logs 1
function logName(name) {
  var n = name || "Fatema";
  console.log(n);
}
logName(); //logs "Fatema"

23. Является ли использование оператора + или унарного плюса самым быстрым способом преобразования строки в число?

Согласно Документации MDN + — это самый быстрый способ преобразования строки в число, поскольку он не выполняет никаких операций над значением, если оно уже является числом.

24. Что такое ДОМ?

DOM означает Объектная модель документа и представляет собой интерфейс (API) для документов HTML и XML. Когда браузер впервые читает (разбирает) наш HTML-документ, он создает большой объект, действительно большой объект на основе HTML-документа, это DOM. Это древовидная структура, созданная на основе HTML-документа. DOM используется для взаимодействия и изменения структуры DOM или отдельных элементов или узлов.

Представьте, что у нас есть такая структура HTML.

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta http-equiv="X-UA-Compatible" content="ie=edge">
   <title>Document Object Model</title>
</head>
<body>
   <div>
      <p>
         <span></span>
      </p>
      <label></label>
      <input>
   </div>
</body>
</html>

Эквивалент DOM будет таким.

Объект document в JavaScript представляет DOM. Он предоставляет нам множество методов, которые мы можем использовать для выбора элементов, обновления содержимого элементов и многого другого.

25. Что такое распространение событий?

Когда событие происходит в элементе DOM, это событие не происходит полностью в одном только этом элементе. На этапе всплытия событие всплывает или переходит к своему родителю, к бабушке и дедушке, к родителю бабушки и дедушки, пока не достигнет window, находясь в Фаза захвата: событие начинается с window до элемента, вызвавшего событие, или event.target.

Распространение событий состоит из трех этапов.

  1. Фаза захвата — событие начинается с window, затем переходит к каждому элементу, пока не достигнет целевого элемента.
  2. Целевая фаза — событие достигло целевого элемента.
  3. Фаза всплытия — событие всплывает вверх от целевого элемента, затем поднимается вверх по каждому элементу, пока не достигнет window.

26. Что такое пузырьковое событие?

Когда событие происходит в элементе DOM, это событие не происходит полностью в одном только этом элементе. На этапе всплытия событие всплывает или переходит к своему родителю, к бабушке и дедушке, к родителю бабушки и дедушки, пока не достигнет window.

Если у нас есть пример такой разметки.

<div class="grandparent">
    <div class="parent">
      <div class="child">1</div>
    </div>
</div>

И наш js-код.

function addEvent(el, event, callback, isCapture = false) {
  if (!el || !event || !callback || typeof callback !== 'function') return;
  if (typeof el === 'string') {
    el = document.querySelector(el);
  };
  el.addEventListener(event, callback, isCapture);
}
addEvent(document, 'DOMContentLoaded', () => {
  const child = document.querySelector('.child');
  const parent = document.querySelector('.parent');
  const grandparent = document.querySelector('.grandparent');
  addEvent(child, 'click', function (e) {
    console.log('child');
  });
  addEvent(parent, 'click', function (e) {
    console.log('parent');
  });
  addEvent(grandparent, 'click', function (e) {
    console.log('grandparent');
  });
  addEvent(document, 'click', function (e) {
    console.log('document');
  });
  addEvent('html', 'click', function (e) {
    console.log('html');
  })
  addEvent(window, 'click', function (e) {
    console.log('window');
  })
});

Метод addEventListener имеет третий необязательный параметр useCapture со значением по умолчанию false событие произойдет на этапе всплытия, если true событие произойдет на этапе захвата . Если мы нажмем на элемент child, он зарегистрирует child, parent, grandparent, html, document и window соответственно на консоли. Это Всплывающие события.

27. Что такое захват событий?

Когда событие происходит в элементе DOM, это событие не происходит полностью в одном только этом элементе. На этапе захвата событие начинается с window вплоть до элемента, вызвавшего событие.

Если у нас есть пример такой разметки.

<div class="grandparent">
    <div class="parent">
      <div class="child">1</div>
    </div>
</div>

И наш js-код.

function addEvent(el, event, callback, isCapture = false) {
  if (!el || !event || !callback || typeof callback !== 'function') return;
  if (typeof el === 'string') {
    el = document.querySelector(el);
  };
  el.addEventListener(event, callback, isCapture);
}
addEvent(document, 'DOMContentLoaded', () => {
  const child = document.querySelector('.child');
  const parent = document.querySelector('.parent');
  const grandparent = document.querySelector('.grandparent');
  addEvent(child, 'click', function (e) {
    console.log('child');
  }, true);
  addEvent(parent, 'click', function (e) {
    console.log('parent');
  }, true);
  addEvent(grandparent, 'click', function (e) {
    console.log('grandparent');
  }, true);
  addEvent(document, 'click', function (e) {
    console.log('document');
  }, true);
  addEvent('html', 'click', function (e) {
    console.log('html');
  }, true)
  addEvent(window, 'click', function (e) {
    console.log('window');
  }, true)
});

Метод addEventListener имеет третий необязательный параметр useCapture со значением по умолчанию false событие произойдет на этапе всплытия, если true событие произойдет на этапе захвата . Если мы нажмем на элемент child, он зарегистрирует window, document, html, grandparent и parent и child соответственно на консоли. Это фиксация событий.

28. В чем разница между методами event.preventDefault() и event.stopPropagation()?

Метод event.preventDefault() предотвращает поведение элемента по умолчанию. При использовании в элементе form он предотвращает его отправку. Если он используется в элементе anchor, он предотвращает навигацию по нему. При использовании в contextmenu он предотвращает его показ или отображение. В то время как метод event.stopPropagation() останавливает распространение события или предотвращает возникновение события на этапе всплытия или захвата.

29. Как узнать, использовался ли в элементе метод event.preventDefault()?

Мы можем использовать свойство event.defaultPrevented в объекте события. Он возвращает boolean, указывающий, был ли вызван event.preventDefault() в конкретном элементе.

30. Почему этот код obj.someprop.x выдает ошибку?

const obj = {};
console.log(obj.someprop.x);

Очевидно, это вызывает ошибку, поскольку мы пытаемся получить доступ к свойству
x в свойстве someprop, имеющем значение undefined. Помните, что свойства в объекте, который не существует сам по себе, и его прототип имеет значение по умолчанию undefined, а undefined не имеет свойства x.

31. Что такое event.target?

Проще говоря, event.target — это элемент, для которого произошло событие, или элемент, который инициировал событие.

Пример HTML-разметки.

<div onclick="clickFunc(event)" style="text-align: center;margin:15px;
border:1px solid red;border-radius:3px;">
    <div style="margin: 25px; border:1px solid royalblue;border-radius:3px;">
        <div style="margin:25px;border:1px solid skyblue;border-radius:3px;">
          <button style="margin:10px">
             Button
          </button>
        </div>
    </div>
 </div>

Пример JavaScript.

function clickFunc(event) {
  console.log(event.target);
}

Если вы нажмете кнопку, она зарегистрирует разметку кнопки, даже если мы прикрепим событие к самому внешнему div, она всегда будет записывать кнопку, поэтому мы можем сделать вывод, что event.target — это элемент, вызвавший событие.

32. Что такое event.currentTarget?

event.currentTarget — это элемент, к которому мы явно прикрепляем обработчик событий.
Пример HTML-разметки:

<div onclick="clickFunc(event)" style="text-align: center;margin:15px;
border:1px solid red;border-radius:3px;">
    <div style="margin: 25px; border:1px solid royalblue;border-radius:3px;">
        <div style="margin:25px;border:1px solid skyblue;border-radius:3px;">
          <button style="margin:10px">
             Button
          </button>
        </div>
    </div>
  </div>

И немного изменим наш JS.

function clickFunc(event) {
  console.log(event.currentTarget);
}

Если вы нажмете кнопку, она зарегистрирует самую внешнюю разметку div, даже если мы нажмем кнопку. В этом примере мы можем сделать вывод, что event.currentTarget — это элемент, к которому мы прикрепляем обработчик событий.

33. В чем разница между == и ===?

Разница между ==(абстрактное равенство) и ===(строгое равенство) заключается в том, что == сравнивается по значению после приведения и === сравнивает по значению и типу без принуждения.

Давайте углубимся в ==. Итак, сначала давайте поговорим о принуждении.

приведение — это процесс преобразования значения в другой тип. Как и в этом случае, == выполняет неявное приведение. У == есть несколько условий, которые необходимо выполнить перед сравнением двух значений.

Предположим, нам нужно сравнить x == y значений.

  1. Если x и y имеют одинаковый тип. Затем сравните их с оператором ===.
  2. Если x равно null, а y равно undefined, вернуть true.
  3. Если x равно undefined, а y равно null, вернуть true.
  4. Если x относится к типу number, а y к типу string, то верните x == toNumber(y).
  5. Если x относится к типу string, а y к типу number, то верните toNumber(x) == y.
  6. Если x имеет тип boolean, то вернуть toNumber(x) == y.
  7. Если y имеет тип boolean, то вернуть x == toNumber(y).
  8. Если x равно string, symbol или number, а y имеет тип object, то вернуть x == toPrimitive(y).
  9. Если x равно object, а x равно string, symbol, то вернуть toPrimitive(x) == y.
  10. Вернуть false.

Примечание. toPrimitive сначала использует метод valueOf, а затем метод toString в объектах, чтобы получить примитивное значение этого объекта.

Давайте примеры.

xyx == y55true1'1'truenullundefinedtrue0falsetrue'1,2'[1,2]true'[object Object]'{}true

Все эти примеры возвращают true.

Первый пример соответствует условию номер один, потому что x и y имеют одинаковый тип и значение.

Второй пример соответствует четвертому условию y перед сравнением преобразуется в number.

Третий пример соответствует второму условию.

Четвертый пример соответствует седьмому условию, потому что y равно boolean.

Пятый пример относится к условию восемь. Массив преобразуется в string с помощью метода toString(), который возвращает 1,2.

Последний пример относится к десятому условию. Объект преобразуется в string с помощью метода toString(), который возвращает [object Object].

xyx === y55true1'1'falsenullundefinedfalse0falsefalse'1,2'[1,2]false'[object Object]'{}false

Если мы используем оператор ===, все сравнения, кроме первого примера, вернут false, потому что они не имеют одного и того же типа, а первый пример вернет true, потому что они имеют одинаковый тип и значение.

34. Почему он возвращает false при сравнении двух похожих объектов в JavaScript?

Предположим, у нас есть пример ниже.

let a = { a: 1 };
let b = { a: 1 };
let c = a;
console.log(a === b); // logs false even though they have the same property
console.log(a === c); // logs true hmm

JavaScript по-разному сравнивает объекты и примитивы. В примитивах они сравниваются по значению, а в объектах сравниваются по ссылке или адресу в память, в которой хранится переменная. Вот почему первый оператор console.log возвращает false, а второй оператор console.log возвращает true. a и c имеют одинаковую ссылку, а a и b - разные.

35. Что означает !! оператор делать?

Оператор Double NOT или !! преобразует значение справа в логическое значение. в основном это причудливый способ преобразования значения в логическое значение.

console.log(!!null); //logs false
console.log(!!undefined); //logs false
console.log(!!''); //logs false
console.log(!!0); //logs false
console.log(!!NaN); //logs false
console.log(!!' '); //logs true
console.log(!!{}); //logs true
console.log(!![]); //logs true
console.log(!!1); //logs true
console.log(!![].length); //logs false

36. Как оценить несколько выражений в одной строке?

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

let x = 5;
x = (x++ , x = addFive(x), x *= 2, x -= 5, x += 10);
function addFive(num) {
  return num + 5;
}

Если вы запишете значение x, оно будет 27. Во-первых, мы увеличиваем значение x, оно должно быть 6, затем мы вызываем функцию addFive(6) и передаем 6 в качестве параметра и присваиваем результат x новому значению x будет 11. После этого мы умножаем текущее значение x на 2 и назначаем его x обновленное значение x будет 22. Затем мы вычитаем текущее значение x из 5 и присваиваем результат x, обновленное значение будет 17. И, наконец, мы увеличиваем значение x на 10 и присваиваем обновленное значение x, теперь значение x будет 27.

37. Что такое подъем?

Поднятие – это термин, используемый для описания перемещения переменных и функций наверх их (глобальных или функциональных) область, где мы определяем эту переменную или функцию.

Хорошо, чтобы понять Поднятие, мне нужно объяснить контекст выполнения.
Контекст выполнения — это «среда кода», которая в настоящее время выполняется. Контекст выполнения состоит из двух фаз: компиляция и выполнение.

Компиляция — на этом этапе он получает все объявления функций и поднимает их наверх их области видимости, чтобы мы могли ссылаться на них позже, и получает все объявление переменных (объявить с помощью ключевого слова var), а также поднимает их и присваивает им значение по умолчанию undefined.

Выполнение — на этом этапе он присваивает значения переменным, поднятым ранее, и выполняет или вызывает функции (методы в объектах).

Примечание. подняты только объявления функций и переменные, объявленные с помощью ключевого слова var, а не функциональные выражения или стрелочные функции, ключевые слова let и const.

Хорошо, предположим, что у нас есть пример кода в глобальной области ниже.

console.log(y);
y = 1;
console.log(y);
console.log(greet("Fatema"));
function greet(name){
  return 'Hello ' + name + '!';
}
var y;

Этот код регистрирует undefined, 1, Hello Fatema! соответственно.

Таким образом, этап компиляции будет выглядеть следующим образом.

function greet(name) {
  return 'Hello ' + name + '!';
}
var y; //implicit "undefined" assignment
//waiting for "compilation" phase to finish
//then start "execution" phase
/*
console.log(y);
y = 1;
console.log(y);
console.log(greet("Fatema"));
*/

например, я прокомментировал назначение переменной и вызов функции.

После завершения этапа компиляции начинается этап выполнения, вызывающий методы и присваивающий значения переменным.

function greet(name) {
  return 'Hello ' + name + '!';
}
var y;
//start "execution" phase
console.log(y);
y = 1;
console.log(y);
console.log(greet("Fatema"));

38. Что такое объем?

Область в JavaScript — это область, в которой у нас есть действительный доступ к переменным или функциям. В JavaScript есть три типа областей видимости. Глобальная область, Функция области и Блочная область действия (ES6).

  • Глобальная область видимости — переменные или функции, объявленные в глобальном пространстве имен, находятся в глобальной области видимости и поэтому доступны везде в нашем коде.
//global namespace
   var g = "global";
   function globalFunc(){
     function innerFunc(){
          console.log(g); // can access "g" because "g" is a 
                             global variable
     }
     innerFunc();
   }
  • Область действия — переменные, функции и параметры, объявленные внутри функции, доступны внутри этой функции, но не за ее пределами.
function myFavoriteFunc(a) {
       if (true) {
          var b = "Hello " + a;
       }
       return b;
   }
   myFavoriteFunc("World");
   console.log(a); // Throws a ReferenceError "a" is not defined
   console.log(b); // does not continue here
  • Область блока — переменные (let,const), объявленные в блоке {}, могут быть доступны только внутри него.
function testBlock(){
   if(true){
     let z = 5;
   }
   return z; 
 }
 testBlock(); // Throws a ReferenceError "z" is not defined

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

/* Scope Chain
   Inside inner function perspective
   inner's scope -> outer's scope -> global's scope
  */

  //Global Scope
  var variable1 = "Comrades";   
  var variable2 = "Sayonara";
  function outer(){
  //outer's scope
    var variable1 = "World";
    function inner(){
    //inner's scope
      var variable2 = "Hello";
      console.log(variable2 + " " + variable1);
    }
    inner();
  }  
  outer(); 
// logs Hello World 
// because (variable2 = "Hello") and (variable1 = "World") are the nearest 
// variables inside inner's scope.

39. Что такое замыкания?

Это, вероятно, самый сложный вопрос из всех этих вопросов, потому что Замыкания — спорная тема. Поэтому я объясню это из того, что я понимаю.

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

Примеры — отличный способ объяснить замыкания.

//Global's Scope
   var globalVar = "abc";
   function a(){
   //testClosures's Scope
     console.log(globalVar);
   }
   a(); //logs "abc" 
   /* Scope Chain
      Inside a function perspective
      a's scope -> global's scope  
   */

В этом примере, когда мы объявляем функцию a, Global Scope является частью a's замыкания.

Причина, по которой переменная globalVar не имеет значения на изображении из-за того, что значение этой переменной может меняться в зависимости от где и когда мы вызываем a function.
Но в нашем примере выше переменная globalVar будет иметь значение abc.

Хорошо, давайте сложный пример.

var globalVar = "global";
var outerVar = "outer"
function outerFunc(outerParam) {
  function innerFunc(innerParam) {
    console.log(globalVar, outerParam, innerParam);
  }
  return innerFunc;
}
const x = outerFunc(outerVar);
outerVar = "outer-2";
globalVar = "guess"
x("inner");

Это напечатает «угадай внешний внутренний». Объяснение этому заключается в том, что когда мы вызываем функцию outerFunc и присваиваем возвращаемое значение функцией innerFunc переменной x, outerParam будет иметь значение outer, даже если мы назначаем новое значение external-2 в переменную outerVar, потому что
переназначение произошло после вызова функции outer, и в то время, когда мы вызываем функцию outerFunc, она ищет значение outerVar в цепочке областей видимости , outerVar будет иметь значение 'outer'. Теперь, когда мы вызываем переменную x, которая имеет ссылку на innerFunc,
innerParam будет иметь значение inner, потому что это значение, которое мы передаем при вызове, а переменная globalVar будет иметь значение догадка, поскольку перед вызовом переменной x мы присваиваем новое значение globalVar, а во время вызова x значение globalVar в _цепочке областей действия_ это
догадка.

У нас есть пример, демонстрирующий проблему неправильного понимания замыкания.

const arrFuncs = [];
for(var i = 0; i < 5; i++){
  arrFuncs.push(function (){
    return i;
  });
}
console.log(i); // i is 5
for (let i = 0; i < arrFuncs.length; i++) {
  console.log(arrFuncs[i]()); // all logs "5"
}

Этот код работает не так, как мы ожидали, из-за замыканий.
Ключевое слово var создает глобальную переменную, и когда мы нажимаем функцию
, мы возвращаем глобальную переменную i. Поэтому, когда мы вызываем одну из этих функций в этом массиве после завершения цикла, она регистрирует 5, поскольку мы получаем
текущее значение i, равное 5, и мы можем получить к нему доступ, поскольку это глобальная переменная. Потому что Closures сохраняет ссылки этой переменной, а не ее значения во время ее создания. Мы можем решить эту проблему, используя IIFES или изменив ключевое слово var на let для блочного охвата.

40. Что такое ложные значения в JavaScript?

const falsyValues = ['', 0, null, undefined, NaN, false];

Значения falsy — это значения, которые при преобразовании в логическое значение становятся falsy.

41. Как проверить, является ли значение ложным?

Используйте логическую функцию или оператор двойного НЕ !!

42. Что делает "use strict"?

"use strict" — это функция ES5 в JavaScript, которая переводит наш код в строгий режим в функциях или целых сценариях. Строгий режим помогает нам избежать ошибок на ранних стадиях нашего кода и добавляет к нему ограничения.

Ограничения, которые накладывает строгий режим.

  • Назначение или доступ к переменной, которая не объявлена.
function returnY(){
    "use strict";
    y = 123;
    return y;
 }
  • Присвоение значения доступной только для чтения или недоступной для записи глобальной переменной;
   "use strict";
   var NaN = NaN;
   var undefined = undefined;
   var Infinity = "and beyond";
  • Удаление неудаляемого свойства.
  "use strict";
   const obj = {};
   Object.defineProperty(obj, 'x', {
      value : '1'
   });  
   delete obj.x;
  • Повторяющиеся имена параметров.
   "use strict";
   function someFunc(a, b, b, c){
   }
  • Создание переменных с помощью функции eval.
"use strict";
 eval("var x = 1;");
 console.log(x); //Throws a Reference Error x is not defined
  • Значение по умолчанию this будет undefined.
  "use strict";
  function showMeThis(){
    return this;
  }
  showMeThis(); //returns undefined

В строгом режиме есть гораздо больше ограничений, чем эти.

43. Каково значение this в JavaScript?

По сути, this относится к значению объекта, который в данный момент выполняет или вызывает функцию. Я говорю в настоящее время по той причине, что значение this меняется в зависимости от контекста, в котором мы его используем, и где мы его используем.

   const carDetails = {
     name: "Ford Mustang",
     yearBought: 2005,
     getName(){
        return this.name;
     },
     isRegistered: true
   };
   console.log(carDetails.getName()); // logs Ford Mustang

Это то, что мы обычно ожидаем, потому что в методе getName мы возвращаем this.name, this в этом контексте относится к объекту, который является объектом carDetails, который в настоящее время является объектом-"владельцем" выполняемой функции.

Хорошо, давайте добавим немного кода, чтобы сделать его странным. Под оператором console.log добавьте эти три строки кода

var name = "Ford Ranger";
var getCarName = carDetails.getName;
console.log(getCarName()); // logs Ford Ranger

Второй оператор console.log печатает слово Ford Ranger, что странно, потому что в нашем первом операторе console.log было напечатано Ford Mustang. Причина этого в том, что метод getCarName имеет другой объект «владелец», которым является объект window. Объявление переменных с ключевым словом var в глобальной области видимости прикрепляет свойства в объекте window с теми же именами, что и переменные. Помните, что this в глобальной области видимости относится к объекту window, когда "use strict" не используется.

console.log(getCarName === window.getCarName); //logs true
console.log(getCarName === this.getCarName); // logs true

this и window в этом примере относятся к одному и тому же объекту.

Один из способов решения этой проблемы — использование методов apply и call в функциях.

console.log(getCarName.apply(carDetails)); //logs Ford Mustang
console.log(getCarName.call(carDetails));  //logs Ford Mustang

Методы apply и call предполагают, что первым параметром будет объект, который будет иметь значение this внутри этой функции.

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

   (function (){
     console.log(this);
   })(); //logs the "window" object
   function iHateThis(){
      console.log(this);
   }
   iHateThis(); //logs the "window" object  
   const myFavoriteObj = {
     guessThis(){
        function getThis(){
          console.log(this);
        }
        getThis();
     },
     name: 'Nury Fatema',
     thisIsAnnoying(callback){
       callback();
     }
   };
   myFavoriteObj.guessThis(); //logs the "window" object
   myFavoriteObj.thisIsAnnoying(function (){
     console.log(this); //logs the "window" object
   });

Если мы хотим получить значение свойства name, которое является Nury Fatema в объекте myFavoriteObj, есть два способа решить эту проблему.

Сначала мы сохраняем значение this в переменной.

const myFavoriteObj = {
     guessThis(){
         const self = this; //saves the this value to the 
                              "self" variable
         function getName(){
           console.log(self.name);
         }
         getName();
     },
     name: 'Nury Fatema',
     thisIsAnnoying(callback){
       callback();
     }
   };

В этом изображении мы сохраняем значение this, которое будет объектом myFavoriteObj. Таким образом, мы можем получить к нему доступ внутри внутренней функции getName.

Во-вторых, мы используем стрелочные функции ES6.

const myFavoriteObj = {
     guessThis(){
         const getName = () => { 
           //copies the value of "this" outside of this 
             arrow function
           console.log(this.name);
         }
         getName();
     },
     name: 'Nury Fatema',
     thisIsAnnoying(callback){
       callback();
     }
   };

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

44. Что такое prototype объекта?

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

  const o = {};
  console.log(o.toString()); // logs [object Object]

Несмотря на то, что метод o.toString не существует в объекте o, он не выдает ошибку, а возвращает строку [object Object]. Когда свойство не существует в объекте, оно ищет его прототип, а если оно все еще не существует, оно ищет прототип прототипа и так далее, пока не найдет свойство с то же самое в цепочке прототипов. Концом цепочки прототипов является Object.prototype.

console.log(o.toString === Object.prototype.toString); // logs true
   // which means we we're looking up the Prototype Chain and it reached 
   // the Object.prototype and used the "toString" method.

45. Что такое IIFE, какая от него польза?

IIFE или Выражение немедленно вызываемой функции – это функция, которая будет вызываться или выполняться после ее создания или объявления. Синтаксис для создания IIFE заключается в том, что мы заключаем function (){} в круглые скобки () или оператор группировки для обработки функции как выражения, а затем вызываем ее с помощью других круглых скобок () . Итак, IIFE выглядит так (function(){})().

(function () {
}());
(function () {
})();
(function named(params) {
})();
(() => {
})();
(function (global) {
})(window);
const utility = (function () {
   return {
      //utilities
   };
})();

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

Наилучшее использование IIFE — создание функций настройки инициализации и избежание конфликтов имен с другими переменными в глобальной области видимости или загрязнения глобального пространства имен. Давайте рассмотрим пример.

<script src="https://w3schools.com/somelibrary.js"></script>

Предположим, у нас есть ссылка на библиотеку somelibrary.js, которая предоставляет некоторые глобальные функции, которые мы можем использовать в нашем коде, но в этой библиотеке есть два метода, которые мы не используем, createGraph и drawGraph, потому что в этих методах есть ошибки. И мы хотим реализовать собственные методы createGraph и drawGraph.

  • Один из способов решить эту проблему — изменить структуру наших скриптов.
<script src="https://w3schools.com/somelibrary.js"></script>
<script>
   function createGraph() {
      // createGraph logic here
   }
   function drawGraph() {
      // drawGraph logic here
   }
</script>

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

  • Другой способ решить эту проблему — изменить имя наших собственных вспомогательных функций.
<script src="https://w3schools.com/somelibrary.js"></script>
<script>
   function myCreateGraph() {
      // createGraph logic here
   }
   function myDrawGraph() {
      // drawGraph logic here
   }
</script>

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

  • Другой способ — использовать IIFE.
<script src="https://w3schools.com/somelibrary.js"></script>
<script>
   const graphUtility = (function () {
      function createGraph() {
         // createGraph logic here
      }
      function drawGraph() {
         // drawGraph logic here
      }
      return {
         createGraph,
         drawGraph
      }
   })();
</script>

В этом решении мы создаем служебную переменную, являющуюся результатом IIFE, которая возвращает объект, содержащий два метода createGraph и drawGraph.

Еще одна проблема, которую решает IIFE, представлена ​​в этом примере.

var li = document.querySelectorAll('.list-group > li');
for (var i = 0, len = li.length; i < len; i++) {
   li[i].addEventListener('click', function (e) {
      console.log(i);
   })
}

Предположим, у нас есть элемент ul с классом list-group и у него есть 5 дочерних элементов li. И мы хотим console.log значение i, когда мы щелкаем отдельный элемент li.
Но поведение, которое мы хотим в этом коде, не работает. Вместо этого он регистрирует 5 при каждом нажатии элемента li. Наша проблема связана с тем, как работают замыкания. Замыкания — это просто способность функций запоминать ссылки на переменные в своей текущей области, в области родительской функции и в глобальной области. Когда мы объявляем переменные с помощью ключевого слова var в глобальной области видимости, очевидно, мы создаем глобальную переменную i. Поэтому, когда мы щелкаем элемент li, он регистрирует 5, потому что это значение i, когда мы ссылаемся на него позже в функции обратного вызова.

  • Одним из решений этой проблемы является IIFE.
var li = document.querySelectorAll('.list-group > li');
for (var i = 0, len = li.length; i < len; i++) {
   (function (currentIndex) {
      li[currentIndex].addEventListener('click', function (e) {
         console.log(currentIndex);
      })
   })(i);
}

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

46. ​​Что такое метод использования Function.prototype.apply?

apply вызывает функцию, определяющую this или объект «владельца» этой функции в момент вызова.

const details = {
  message: 'Hello World!'
};
function getMessage(){
  return this.message;
}
getMessage.apply(details); // returns 'Hello World!'

Этот метод работает так же, как и Function.prototype.call, с той лишь разницей, что мы передаем аргументы. В apply мы передаем аргументы в виде массива.

const person = {
  name: "Nury Fatema"
};
function greeting(greetingMessage) {
  return `${greetingMessage} ${this.name}`;
}
greeting.apply(person, ['Hello']); // returns "Hello Nury Fatema!"

47. Что такое метод использования Function.prototype.call?

call вызывает функцию, определяющую this или объект «владельца» этой функции в момент вызова.

const details = {
  message: 'Hello World!'
};
function getMessage(){
  return this.message;
}
getMessage.call(details); // returns 'Hello World!'

Этот метод работает так же, как Function.prototype.apply, единственное отличие состоит в том, как мы передаем аргументы. В call мы передаем непосредственно аргументы, разделяя их запятой , для каждого аргумента.

const person = {
  name: "Nury Fatema"
};
function greeting(greetingMessage) {
  return `${greetingMessage} ${this.name}`;
}
greeting.call(person, 'Hello'); // returns "Hello Nury Fatema!"

48. В чем разница между Function.prototype.apply и Function.prototype.call?

Единственная разница между apply и call заключается в том, как мы передаем аргументы в вызываемую функцию. В apply мы передаем аргументы в виде массива, а в call мы передаем аргументы непосредственно в списке аргументов.

const obj1 = {
 result:0
};
const obj2 = {
 result:0
};
function reduceAdd(){
   let result = 0;
   for(let i = 0, len = arguments.length; i < len; i++){
     result += arguments[i];
   }
   this.result = result;
}
reduceAdd.apply(obj1, [1, 2, 3, 4, 5]); // returns 15
reduceAdd.call(obj2, 1, 2, 3, 4, 5); // returns 15

49. Каково использование Function.prototype.bind?

Метод bind возвращает новую функцию, связанную
с определенным значением this или объектом "владелец", поэтому мы можем использовать его позже в нашем коде. Методы call, apply вызывают функцию немедленно, а не возвращают новую функцию, как метод bind.

import React from 'react';
class MyComponent extends React.Component {
     constructor(props){
          super(props); 
          this.state = {
             value : ""
          }  
          this.handleChange = this.handleChange.bind(this); 
          // Binds the "handleChange" method to the 
             "MyComponent"  component
     }
     handleChange(e){
       //do something amazing here
     }
     render(){
        return (
              <>
                <input type={this.props.type}
                        value={this.state.value}
                     onChange={this.handleChange}                      
                  />
              </>
        )
     }
}

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

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

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

  • Метод map создает новый массив с результатами вызова предоставленной функции обратного вызова для каждого элемента массива.
const words = ["Functional", "Procedural", "Object-Oriented"];
const wordsLength = words.map(word => word.length);
  • Метод filter создает новый массив со всеми элементами, прошедшими проверку в функции обратного вызова.
const data = [
  { name: 'Momin', isRegistered: true },
  { name: 'Hasan', isRegistered: false },
  { name: 'Rafi', isRegistered: true }
];
const registeredUsers = data.filter(user => user.isRegistered);
  • Метод reduce применяет функцию к аккумулятору и каждому элементу массива (слева направо), чтобы уменьшить его до одного значения.
const strs = ["I", " ", "am", " ", "Iron", " ", "Man"];
const result = strs.reduce((acc, currentStr) => acc + currentStr, "");

51. Что такое функции высшего порядка?

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

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

52. Почему функции называются объектами первого класса?

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

53. Реализуйте метод Array.prototype.map вручную.

function map(arr, mapCallback) {
  // First, we check if the parameters passed are right.
  if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== 'function') { 
    return [];
  } else {
    let result = [];
    // We're making a results array every time we call this function
    // because we don't want to mutate the original array.
    for (let i = 0, len = arr.length; i < len; i++) {
      result.push(mapCallback(arr[i], i, arr)); 
      // push the result of the mapCallback in the 'result' array
    }
    return result; // return the result array
  }
}

Как описание MDN метода Array.prototype.map.

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

Остальные будут перечислены в разделе «JavaScript-интервью — вопросы с ответами, на которых нужно сосредоточиться в 2020 году для начинающих — ЧАСТЬ 2».

Удачного обучения!…….