Практикум №4

Описание задания вы всегда можете посмотреть под спойлером.



В предыдущем уроке наш конечный код был такой:

Код

let money, time;

function start() {
  money = +prompt('Ваш бюджет на месяц?', '');
  time = prompt('Введите дату в формате YYYY-MM-DD', '');

  while( isNaN(money) || money == null || money == '' ) {
  money = +prompt('Введите ваш бюджет на месяц', '');
  }
}
start();

let appData = {
  budget: money,
  timeData: time,
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false
}

function chooseExpenses() {
  for( let i = 0; i < 2; i++) {
  let a = prompt('Введите обязательную статью расходов в этом месяце', ''),
  b = prompt('Во сколько обойдётся?', '');
   
  if( typeof(a) != null && typeof(b) != null && a != '' && b != '' && a.length < 50) {
   
  appData.expenses[a] = b;  
  } else {
  i--;
  }
   
  }
}
chooseExpenses();

function detectDayBudget() {
  appData.moneyPerDay = ( appData.budget / 30 ).toFixed(2);
  alert( appData.moneyPerDay );
}
detectDayBudget();

function checkSavings() {
  if (appData.savings == true) {
  let save = +prompt('Какова сумма накоплений?', ''),
  percent = +prompt('Под какой процент?', '');

  appData.monthIncome = save / 100 / 12 * percent;
  alert('Доход в месяц с вашего депозита: ' + appData.monthIncome);
  }
}
checkSavings();

function detectLevel() {
  if(appData.moneyPerDay < 500) {
  console.log('Низкий уровень дохода');
  } else if(appData.moneyPerDay > 500 && appData.moneyPerDay < 1000) {
  console.log('Средний уровень дохода');
  } else if(appData.moneyPerDay > 1000) {
  console.log('Высокий уровень дохода');
  } else {
  console.log('Что-то пошло не так');
  }
}
detectLevel();

function chooseOptExpenses() {
  for (let i = 1; i <= 3; i++) {
  let questionOptExpenses = prompt('Статья необязательных расходов?', '');

  appData.optionalExpenses[i] = questionOptExpenses;
  console.log(appData.optionalExpenses);
  }
}
chooseOptExpenses();


были определены все функции в отдельности. Задача этого урока объединить все эти функции в наш объект appData, превратив их в методы (поскольку методы объекта это и есть функции).

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

Берём код нашего объекта appData:

Код

let appData = {
  budget: money,
  timeData: time,
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false
}


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

Код

let appData = {
  budget: money,
  timeData: time,
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false,
  chooseExpenses: function() {
   
  }
}


теперь берём нашу функцию chooseExpenses() из кода предыдущего урока:

Код

function chooseExpenses() {
  for( let i = 0; i < 2; i++) {
  let a = prompt('Введите обязательную статью расходов в этом месяце', ''),
  b = prompt('Во сколько обойдётся?', '');
   
  if( typeof(a) != null && typeof(b) != null && a != '' && b != '' && a.length < 50) {
   
  appData.expenses[a] = b;  
  } else {
  i--;
  }
   
  }
}
chooseExpenses();


и всё, что находится в её теле (между фигурными скобками)

Код

  for( let i = 0; i < 2; i++) {
  let a = prompt('Введите обязательную статью расходов в этом месяце', ''),
  b = prompt('Во сколько обойдётся?', '');
   
  if( typeof(a) != null && typeof(b) != null && a != '' && b != '' && a.length < 50) {
   
  appData.expenses[a] = b;  
  } else {
  i--;
  }
   
  }


помещаем в тело функции метода chooseExpenses:

Код

let appData = {
  budget: money,
  timeData: time,
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false,
  chooseExpenses: function() {
  for( let i = 0; i < 2; i++) {
  let a = prompt('Введите обязательную статью расходов в этом месяце', ''),
  b = prompt('Во сколько обойдётся?', '');
   
  if( typeof(a) != null && typeof(b) != null && a != '' && b != '' && a.length < 50) {
   
  appData.expenses[a] = b;  
  } else {
  i--;
  }
   
  }
  }
}


оставшийся код:

Код

function chooseExpenses() {
   

}
chooseExpenses();


можно удалить, он нам больше не нужен.

По такому же принципу мы поступаем с остальными функциями: detectDayBudget, checkSavings, detectLevel, chooseOptExpenses.

В итоге конечный код нашего объекта appData будет выглядеть так:

Код

let appData = {
  budget: money,
  timeData: time,
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false,
  chooseExpenses: function() {
  for( let i = 0; i < 2; i++) {
  let a = prompt('Введите обязательную статью расходов в этом месяце', ''),
  b = prompt('Во сколько обойдётся?', '');
   
  if( typeof(a) != null && typeof(b) != null && a != '' && b != '' && a.length < 50) {
   
  appData.expenses[a] = b;  
  } else {
  i--;
  }
   
  }
  },
  detectDayBudget: function() {
  appData.moneyPerDay = ( appData.budget / 30 ).toFixed(2);
  alert( appData.moneyPerDay );
  },
  checkSavings: function() {
  if (appData.savings == true) {
  let save = +prompt('Какова сумма накоплений?', ''),
  percent = +prompt('Под какой процент?', '');
   
  appData.monthIncome = save / 100 / 12 * percent;
  alert('Доход в месяц с вашего депозита: ' + appData.monthIncome);
  }
  },
  detectLevel: function() {
  if(appData.moneyPerDay < 500) {
  console.log('Низкий уровень дохода');
  } else if(appData.moneyPerDay > 500 && appData.moneyPerDay < 1000) {
  console.log('Средний уровень дохода');
  } else if(appData.moneyPerDay > 1000) {
  console.log('Высокий уровень дохода');
  } else {
  console.log('Что-то пошло не так');
  }
  },
  chooseOptExpenses: function() {
  for (let i = 1; i <= 3; i++) {
  let questionOptExpenses = prompt('Статья необязательных расходов?', '');
   
  appData.optionalExpenses[i] = questionOptExpenses;
  console.log(appData.optionalExpenses);
  }
  }

}


В нашем объекте appData есть свойство income, у которого в качестве значения пока что пустой массив:

Код
income: []


чтобы получить данные для заполнения этого пустого массива, мы в объекте appData создадим новый метод, назовём его chooseIncome, в качестве его значения также пропишем функцию:

Код

  chooseIncome: function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  appData.income = items.split(', ');
  }


внутри функции я создал переменную items, в которую будет в виде строки сохранён ответ пользователя на вопрос в модальном окне 'Что принесёт дополнительный доход? (Перечислите через запятую)'.

Далее мы используем метод split() Метод split() разделяет строку на подстроки, в итоге мы получаем массив подстрок, который и попадёт в пустой массив в методе income.

В круглых скобках у метода split() мы поставили запятую, за счёт этого строка, полученная от пользователя, разбивается на подстроки по запятым (именно поэтому мы, задавая вопрос пользователю, попросили его перечислить ответы через запятую!), и затем возвращается массив подстрок.

У нас также была поставлена задача после основного вопроса пользователю задать ещё один, уточняющий вопрос "Может быть что-то еще?".
Можно реализовать это аналогично, создав новую переменную и сохранив в неё значения, полученные от пользователя через команду prompt().

Но мы в этот раз сократим наш код, несколько его оптимизируем: без создания новой переменной мы сразу передадим полученные через prompt() значения в объект income:

Код

  chooseIncome: function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  appData.income = items.split(', ');

  appData.income.push( prompt('Может быть что-то еще?', '') );
  }


Так как значение свойства income это массив данных, то мы смогли использовать команду push(), чтобы добавить новый элемент в конец массива.
А в качестве нового элемента у нас будет строка, ответ пользователя на вопрос "Может быть что-то еще?"

Давайте еще отсортируем по алфавиту наш массив, для этого мы воспользуемся методом sort() :

Код

  chooseIncome: function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  appData.income = items.split(', ');
  appData.income.push( prompt('Может быть что-то еще?', '') );
  appData.income.sort();
  }


Теперь, если мы запустим наш файл index.html в браузере, то сначала увидим окно с вопросом о бюджете:



затем окно с просьбой ввести дату в определённом формате:



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

Откройте в браузере консоль и введите команду вызова метода chooseIncome:

Код
appData.chooseIncome();


нажмите Enter и тут же появится диалоговое окно:



Введите в него через запятую несколько вариантов ответов, нажмите "Ок" и после этого появится второе диалоговое окно, на этот раз с уточняющим вопросом:



добавьте в него свой ответ и нажмите "Ок"

После чего выведите в консоль наш объект appData с помощью команды:

Код
console.log(appData);


я также ввёл какие-то свои варианты ответов, и в консоли видно, что теперь наш массив у свойства income заполнен данными, и они отобразились чётко по алфавиту:



Давайте теперь добавим проверку в наш метод chooseIncome, проверять мы будем, что пользователь при ответе может ввести только строку (на самом деле, любая информация, полученная с помощью prompt(), возвращается в виде строки, но тут проверка нужна из-за метода split() ), также нужна проверка, что пользователь не оставит строку пустой, либо не попытается нажать "Отмена" при ответе на вопрос.

я написал такую проверку через цикл while:

Код

  chooseIncome: function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  while( typeof(items) != 'string' || typeof(items) == null || items == '') {
  items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  }
  appData.income = items.split(', ');
  appData.income.push( prompt('Может быть что-то еще?', '') );
  appData.income.sort();
  }


теперь, до тех пор, пока пользователь корректно не ответит на вопрос 'Что принесёт дополнительный доход? (Перечислите через запятую)', ему так и будет задаваться этот вопрос.

Выведем на экран сообщение о способах дополнительного заработка, используя метод перебора массива forEach.
У нас значением свойства income как раз и является массив, помните? Поэтому:

Код

  appData.income.forEach( function( itemmassive, i) {
  alert('Способы дополнительного заработка: ' + (i+1) + ' - ' + itemmassive );
  } ) ;


здесь itemmassive - каждый из элементов нашего массива
i - его номер

так как по условию задачи нужно вывести способы заработка с нумерацией, начиная с 1, то в alert мы прописываем i + 1

теперь полный код нашего метода chooseIncome такой:

Код

  chooseIncome: function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  while( typeof(items) != 'string' || typeof(items) == null || items == '') {
  items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  }
  appData.income = items.split(', ');
  appData.income.push( prompt('Может быть что-то еще?', '') );
  appData.income.sort();

  appData.income.forEach( function( itemmassive, i) {
  alert('Способы дополнительного заработка: ' + (i+1) + ' - ' + itemmassive );
  } ) ;
  }


И последней нашей задачей будет вывод в консоль сообщение "Наша программа включает в себя данные: " и после этого сообщения содержимое нашего объекта appData.
Используем для этого цикл for in, который, как вы знаете, проходит по перечисляемым свойствам объекта и имеет такую структуру:

Код
for (variable in object) { ... }


где variable - очередное имя свойства объекта для каждой итерации
object - тот объект, по которому мы непосредственно проходим циклом

Применительно к нашей задаче:

Код

for( let key in appData) {
  console.log( 'Наша программа включает в себя данные: ' + key + ' - ' + appData[key] );
}


На этом всё по данному уроку. Полный скрипт к концу этого урока должен выглядеть так:

Код

let money, time;

function start() {
  money = +prompt('Ваш бюджет на месяц?', '');
  time = prompt('Введите дату в формате YYYY-MM-DD', '');

  while( isNaN(money) || money == null || money == '' ) {
  money = +prompt('Введите ваш бюджет на месяц', '');
  }
}
start();

let appData = {
  budget: money,
  timeData: time,
  expenses: {},
  optionalExpenses: {},
  income: [],
  savings: false,
  chooseExpenses: function() {
  for( let i = 0; i < 2; i++) {
  let a = prompt('Введите обязательную статью расходов в этом месяце', ''),
  b = prompt('Во сколько обойдётся?', '');
   
  if( typeof(a) != null && typeof(b) != null && a != '' && b != '' && a.length < 50) {
   
  appData.expenses[a] = b;  
  } else {
  i--;
  }
   
  }
  },
  detectDayBudget: function() {
  appData.moneyPerDay = ( appData.budget / 30 ).toFixed(2);
  alert( appData.moneyPerDay );
  },
  checkSavings: function() {
  if (appData.savings == true) {
  let save = +prompt('Какова сумма накоплений?', ''),
  percent = +prompt('Под какой процент?', '');
   
  appData.monthIncome = save / 100 / 12 * percent;
  alert('Доход в месяц с вашего депозита: ' + appData.monthIncome);
  }
  },
  detectLevel: function() {
  if(appData.moneyPerDay < 500) {
  console.log('Низкий уровень дохода');
  } else if(appData.moneyPerDay > 500 && appData.moneyPerDay < 1000) {
  console.log('Средний уровень дохода');
  } else if(appData.moneyPerDay > 1000) {
  console.log('Высокий уровень дохода');
  } else {
  console.log('Что-то пошло не так');
  }
  },
  chooseOptExpenses: function() {
  for (let i = 1; i <= 3; i++) {
  let questionOptExpenses = prompt('Статья необязательных расходов?', '');
   
  appData.optionalExpenses[i] = questionOptExpenses;
  console.log(appData.optionalExpenses);
  }
  },
  chooseIncome: function() {
  let items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  while( typeof(items) != 'string' || typeof(items) == null || items == '') {
  items = prompt('Что принесёт дополнительный доход? (Перечислите через запятую)', '');
  }
  appData.income = items.split(', ');
  appData.income.push( prompt('Может быть что-то еще?', '') );
  appData.income.sort();

  appData.income.forEach( function( itemmassive, i) {
  alert('Способы дополнительного заработка: ' + (i+1) + ' - ' + itemmassive );
  } ) ;
  }

};

for( let key in appData) {
  console.log( 'Наша программа включает в себя данные: ' + key + ' - ' + appData[key] );
}


Протестировать работу скрипта

Комментарии к материалу: