Кто-нибудь может объяснить цикл forEach?

#javascript #arrays #function #object #ecmascript-6

#javascript #массивы #функция #объект #ecmascript-6

Вопрос:

Хорошо, итак, вот что я знаю о forEach.

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

 function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split('')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
};

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

// Using a for loop

for(let i = 0; i < suspects.length; i  ){
    suspectsList.push(CreateSuspectsObjects(suspects[i]))
};
  

Как я уже сказал, я все еще изучаю JS и на самом деле не понимаю цикл forEach. Я пробовал suspects.forEach(CreateSuspectObjects), но для меня это просто не имеет никакого смысла.

Ответ №1:

forEach Цикл — это просто способ упростить традиционный for цикл. Вы передаете ему функцию, которая является просто тем, что обычно входит в {} цикл for. Однако при работе с функцией вам необходимо знать порядок параметров:

 item
index
array
  

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

 arr.forEach((item, index) => doSomething.with(index));
  

Обратите внимание, что приведенное выше вызывается функцией со стрелкой, и это новая функция ES6. Это эквивалент:

 arr.forEach(function(item, index) {
  doSomething.with(index);
});
  

Ответ №2:

Перевод вашего текущего кода для эквивалентной работы с использованием Array.prototype.forEach() вместо for цикла требует минимальных изменений:

 function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split(' ')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
}

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

// Using forEach()
suspects.forEach((name, i, suspects) => {
  // use name instead of suspects[i]
  suspectsList.push(CreateSuspectObjects(name))
});

console.log(suspectsList);  

Однако, поскольку вы создаете новый массив путем преобразования каждого объекта в существующем массиве, вам следует использовать Array.prototype.map() вместо:

 function CreateSuspectObjects (name) {
  return {
    name, // short-hand for name: name
    color: name.split(' ')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
}

const suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

// Using map()
const suspectsList = suspects.map(name => {
  return CreateSuspectObjects(name);
});

console.log(suspectsList);  

Вы можете еще больше сжать это, поскольку name => { return CreateSuspectObjects(name); } делает в точности то же самое, что и CreateSuspectObjects , изменив оператор на

 const suspectsList = suspects.map(CreateSuspectObjects);
  

array.forEach() против. array.map()

Причина, по которой suspects.forEach(CreateSuspectObjects); не сработало, связана с разницей между forEach() и map() . forEach() выполняет цикл по каждому значению в suspects и выполняет функцию, предусмотренную для ее побочного эффекта. В моем первом фрагменте побочным эффектом является suspectsList.push() , который добавляет значение к существующему массиву suspectsList .

Однако, CreateSuspectObjects() не имеет никаких побочных эффектов; он просто возвращает объект, который forEach() будет игнорироваться, поскольку возвращаемое значение функции не используется.

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

Ответ №3:

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

 function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split('')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
};

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

suspects.forEach(s => {
    suspectsList.push(CreateSuspectsObjects(s))
};
  

Ответ №4:

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

Он будет выполнять итерации по suspects массиву и ссылаться на каждый его объект внутри массива последовательно, точно так же, как это делает i . Здесь я ссылаюсь на каждый из них как suspect , чтобы было легче понять, затем вы помещаете его в массив точно так же, как вы делаете с suspects[i] .

Об операторе arrow смотрите здесь, если вы не знаете, как это работает.

 function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split('')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
};

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

suspects.forEach(suspect => suspectsList.push(CreateSuspectObjects(suspect)))
console.log(suspectsList)  

Комментарии:

1. хорошо, я вижу, что произошло, и мое непонимание…. Мне пришлось загуглить оператор arrow, но то, что я делал, продолжало выдавать мне ошибку, передавало ‘suspects’ обратно в CreateSuspectObjects.