Реализовать функцию подсчёта суммы значений объекта

Помогите, пожалуйста, разобраться где проблема. Необходимо реализовать функцию, где в свойство summary будут суммироваться все значения объекта. Само summary, конечно, из вычислений исключается. На данный момент получается так:

const calcSummaryRate = function (dailyRation) {
  return {
    breakfast: dailyRation.breakfast,
    lunch: dailyRation.lunch,
    "coffee-break": dailyRation["coffee-break"],
    "afternoon-tea": dailyRation["afternoon-tea"],
    dinner: dailyRation.dinner,

    summary: function () {
      const summary = "summary";
      dailyRation[summary] = 0;
      for (let prop in dailyRation) {
        if (prop !== "summary") {
          result += dailyRation[prop]}
      };
      return result;
    }
  } 
}

Сам подсчет реализуется и с reduce:

result = Object.values(dailyRation).reduce((a, b) => a + b, 0);

Но в функции ничего не работает - результат нулевой. Ткните, пожалуйста, где ошибка.

Код для проверки:

const calcSummaryRate = function (dailyRation) {
  return {
    breakfast: dailyRation.breakfast,
    lunch: dailyRation.lunch,
    "coffee-break": dailyRation["coffee-break"],
    "afternoon-tea": dailyRation["afternoon-tea"],
    dinner: dailyRation.dinner,

    summary: function () {
      const summary = "summary";
      dailyRation[summary] = 0;
      for (let prop in dailyRation) {
        if (prop !== "summary") {
          result += dailyRation[prop]}
      };
      return result;
    }
  } 
}

let mondayRation = {
  breakfast: 1240,
  lunch: 765,
  dinner: 564,
};
mondayRation = calcSummaryRate(mondayRation);
console.log(mondayRation.summary);

const tuesdayRation = {
  breakfast: 780,
  "coffee-break": 115,
  lunch: 975,
  "afternoon-tea": 230,
  dinner: 441,
  summary: 0,
};
calcSummaryRate(tuesdayRation);
console.log(tuesdayRation.summary);


Ответы (2 шт):

Автор решения: Grundy
  1. значением поля summary является функция. Для получения значения ее нужно вызвать (добавить () -> mondayRation.summary()), либо переделать ее на свойство, воспользовавшись get

  2. В цикле изменяется переменная result, которая нигде не объявлена, нужно объявить ее вместо dailyRation[summary] = 0

"use strict";

const calcSummaryRate = function(dailyRation) {
  return {
    breakfast: dailyRation.breakfast,
    lunch: dailyRation.lunch,
    "coffee-break": dailyRation["coffee-break"],
    "afternoon-tea": dailyRation["afternoon-tea"],
    dinner: dailyRation.dinner,

    get summary() {
      const summary = "summary";
      let result = 0;
      for (let prop in dailyRation) {
        if (prop !== "summary") {
          result += dailyRation[prop]
        }
      };
      return result;
    }
  }
}

let mondayRation = {
  breakfast: 1240,
  lunch: 765,
  dinner: 564,
};
mondayRation = calcSummaryRate(mondayRation);
console.log(mondayRation.summary);

→ Ссылка
Автор решения: SwaD

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

Для одного объекта в частном случае это будет выглядеть так:

const tuesdayRation = {
  breakfast: 780,
  "coffee-break": 115,
  lunch: 975,
  "afternoon-tea": 230,
  dinner: 441,
  summary: 0,
};

Object.defineProperty(tuesdayRation, 'summary', {
  enumerable: false,
  get: function() {
    return Object.values(this).reduce((a, c) => a += c, 0);
  }
});

console.log(tuesdayRation.summary);

Если объектов много, то можно обернуть назначение свойств ключу в функцию:

const mondayRation = {
  breakfast: 1240,
  lunch: 765,
  dinner: 564,
  summary: 400000
};

const tuesdayRation = {
  breakfast: 780,
  "coffee-break": 115,
  lunch: 975,
  "afternoon-tea": 230,
  dinner: 441,
  summary: 0,
};

function setSummary(obj) {
  Object.defineProperty(obj, 'summary', {
    enumerable: false,
    get: function() {
      return Object.values(this).reduce((a, c) => a += c, 0);
    }
  });
}

setSummary(tuesdayRation);
setSummary(mondayRation);

console.log(tuesdayRation.summary);
console.log(mondayRation.summary);

→ Ссылка