.forEach в массиве с объектами не запускается

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

Нравится: {english_period1: 10, english_period2: 7} <Пример

Но если я хочу запустить array.prototype.forEach, чтобы что-то сделать с метками внутри массива. Он абсолютно ничего не возвращает. .ForEach даже не запустится.

Это сценарий:

// Make new variable which will store the marks
let allMarks = [];

document.querySelector("#marks").addEventListener('submit', e => {
  e.preventDefault();

  //Execute for each input
  for(let i = 0; i < e.srcElement.length-1; i++){
    // Assign name and value
    const name = e.srcElement[i].name;
    const value = e.srcElement[i].value;

    //Check if value is a mark (number)
    if (value % 1 == 0 && value <= 10){
      //Assign mark
      allMarks[name] = value;
    }else{
      //Value is not a mark, check if it's a O, V or G
      if (value == "O" || value == "V" || value == "G"){
        allMarks[name] = value;
      }else{
        console.info("Niet toegestaan");
      }
    }
  }

  allMarks.forEach(mark => {
    console.info("hello world");
  });

},false);

Что он делает:

  1. После того, как пользователь поставил свои отметки, щелкнул и отправил форму
  2. Просмотрите все входные данные в форме и поместите имя плюс значение как объект в массив.
  3. Просмотрите каждую вещь в массиве и напечатайте «hello world» в консоли.

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

Что я делаю неправильно? Разве нельзя использовать array.prototype.forEach над массивом, содержащим объекты? Как мне оптимизировать этот фрагмент кода?

Заранее спасибо!

ОТВЕЧАТЬ

Вместо использования: allMarks[name] = value, который не будет добавлять элемент в массив allMarks = []. Использование allMarks.push({name: name, value: value}); поможет. Потому что теперь он добавит элемент в массив (объект), и, таким образом, forEach может перебирать каждый элемент и получать его значения, как обычный объект.

Особая благодарность: @mhodges

ДЛИННЫЙ ОТВЕТ

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

Можно динамически добавлять ключи к объекту с помощью objectName[variableName]. С помощью Object.keys(objectName) вы можете перебрасывать ключи в массив и перебирать ключи. Это приведет (в моем случае) к более красивой структуре данных:

Вместо: [{field: "English", period: "period_1", mark: "7.5"}] Это вернет:

"English": {
 "period_1": 7.5,
 "period_2": 6.4
}

Я не думаю, что allMarks[name] = value делает то, что вы думаете. Вы устанавливаете свойства в массиве, а не заполняете массив значениями - поэтому .forEach() не выполняет итерацию - в массиве нет элементов. Попробуйте вместо этого использовать allMarks.push(value) и посмотрите, сработает ли это для вас.

mhodges 16.10.2018 18:12

Примечание: allMarks будет массивом строк, а не массивом объектов.

mhodges 16.10.2018 18:13

Другое примечание: этот код работает, но не так, как хотелось бы. Это: allMarks[name] = value создаст / перезапишет свойство объекта с ключом, равным значению содержимого переменной name, и значением, равным значению переменной value. Это свойство объекта будет помещено в объект-массив с именем allMarks, но не добавляет элемент массива. Это легко проверить: console.info(allMarks[name]); как последняя строка в цикле for().

Randy Casburn 16.10.2018 18:17

Спасибо @mhodges! Оно работает! Вместо того, чтобы делать allMarks[name] = value;, который делает что-то, чего я до сих пор не понимаю. Делаю allMarks.push({name: name, value: value}); работает. Потому что теперь я могу перебирать каждый элемент в массиве и получать его имя и значение. Именно то, что я хочу, но я бы предпочел объект, чтобы я мог набрать: например, english_period1.value. Не мог понять, так что это был для меня более понятный вариант. Спасибо еще раз!

Melvin Idema 16.10.2018 18:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
173
4

Ответы 4

Обратите внимание, что немного сложно сказать, что именно вы здесь пытаетесь сделать. Если вы используете необходимостьallMarks как массив, вам нужно добавить каждый отдельный mark в массив allMarks, как показано ниже:

// Make new variable which will store the marks
let allMarks = [];

document.querySelector("#marks").addEventListener('submit', e => {
  e.preventDefault();

  //Execute for each input
  for(let i = 0; i < e.srcElement.length-1; i++){
    // Assign name and value
    const name = e.srcElement[i].name;
    const value = e.srcElement[i].value;
    // <-- create new mark object -->
    const newMark = {name: value}

    //Check if value is a mark (number)
    if (value % 1 == 0 && value <= 10){
      //Assign mark
      //<-- instead of allMarks[name] = value; -->
      //<-- you need to add the newMark to the allMarks array -->
      allMarks.push(newMark);
    }else{
      //Value is not a mark, check if it's a O, V or G
      if (value == "O" || value == "V" || value == "G"){
        //<-- same thing here -->
        allMarks.push(newMark);
      }else{
        console.info("Niet toegestaan");
      }
    }
  }

  allMarks.forEach(mark => {
    console.info("hello world");
  });

},false);

Однако вместо этого вы можете сделать allMarks объектом, а затем установить каждый отдельный mark в качестве пары ключ-значение для этого объекта. Вы по-прежнему сможете перебирать пары ключ, значение в объекте, но не сможете использовать .forEach.

Что бы вы предпочли?

Я думаю, что будет проще, если вы создадите как объект, а не как массив.

например.

var allMarks = {};

и внутри вы можете использовать

var marks;
marks.name = name;
marks.value = value;
allMarks.push(marks);

тогда вы можете использовать

allMarks.forEach(function(mark){
  console.info(mark.name);
  console.info(mark.value);
});
.forEach не является свойством по умолчанию для объектов JS.
kyle 16.10.2018 18:26

Как и .push()

mhodges 16.10.2018 18:54

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

Melvin Idema 16.10.2018 18:55

Ваш allMarks[name] = value превращает массив allMarks в массив с буквальными свойствами (с поведением объекта), .forEach() не будет запускаться с этим. Вы можете использовать allMarks как объект:

let allMarksKeys = Object.keys(allMarks); 
allMarksKeys.forEach(key => // for example use allmarks[key] to access object elements)

и т.п.

forEach будет работать с массивами, но индекс массива должен быть числовым (целочисленное значение).

Другие вопросы по теме