«Единственный способ творить великие дела – это любить то, что ты делаешь»
JavaScript


Игра на «Морской Бой» на JavaScript: Простая Игра и Игра для Двоих


Продолжается практическая работа с кодом JavaScript. Это четвертая по счету практическая задача.

Здесь нужно будет рефакторить код из предыдущей задачи: код будет преобразовываться с использованием объектов.

Рефакторинг - это перепроектирование кода, переработка кода, преобразование алгоритмов — процесс изменения внутренней структуры программы.

1) У нас уже есть рабочее приложение (см. ниже исходный код - из прошлого задания), состоящее из отдельных функций.

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

2) Создать метод toggleVisibleMyDB, который при вызове будет проверять свойство privat. Если оно false - он переключает его в true, если true - переключает в false. Протестировать вместе с showMyDB.

3) В методе writeYourGenres запретить пользователю нажать кнопку "Отмена" или оставлять пустую строку. Если он это сделал - возвращать его к этому же вопросу.

После того, как все жанры введены - при помощи метода forEach вывести в консоль сообщения в таком виде: "Любимый жанр #(номер по порядку, начиная с 1) - это (название из массива)"

Код взять из предыдущего домашнего задания.



Исходный код - из прошлого задания

Функции из кода, представленного ниже, должны быть перезаписаны как методы объекта personalMovieDB.


/* Объявляем переменную numberOfFilms глобально, чтобы работать с ней внутри функции */
let numberOfFilms;

// 1. Функция для проверки введенных данных при ответе на 1-ый вопрос
function start(){
    numberOfFilms = +prompt('Сколько фильмов вы уже посмотрели?');
    /* Проверка: на пустое поле для ввода ИЛИ на кнопку Отмена ИЛИ 
       на НЕ число, то снова задаем вопрос... */
    while(numberOfFilms == '' || numberOfFilms == null || isNaN(numberOfFilms)){
        numberOfFilms = +prompt('Сколько фильмов вы уже посмотрели?');
    } 
}
start(); // Вызов функции

// --------- Главный объект программы ---------
const personalMovieDB = {
    count: numberOfFilms,
    movies: {},
    actors: {},
    genres: [],
    private: false
};

// 2. Функция заносит в главный объект программы информацию о фильмах
function rememberMyFilms(){
    for (let i = 0; i < 2; i++) {
        const a = prompt(`Один из последних просмотренных фильмов ${i + 1}`),
              b = prompt('На сколько оцените его?');   
        /* Проверка на пустое поле для ввода ИЛИ на кнопку Отмена ИЛИ на количество символов */
        if(a != '' && b != '' && a != null && b != null && a.length < 50) {
            personalMovieDB.movies[a] = b; 
            console.log('done');
        }
        else{
            console.log('error');
            i--; 
        }
    }
}
rememberMyFilms(); // Вызов функции

// 3. Функция анализа уровня Киномании
function detectPersonalLevel(){
    if (personalMovieDB.count < 10) {
        console.log('Просмотрено довольно мало фильмов');
    } else if (personalMovieDB.count > 10 && personalMovieDB.count < 30) {
        console.log('Вы классический зритель');
    } else if (personalMovieDB.count > 30) {
        console.log('Вы киноман');
    } else {
        console.log('Произошла ошибка');
    }
}
detectPersonalLevel(); // Вызов функции

// 4. Функция Жанров - 3-я часть задания
function writeYourGenres(){
    for(let i = 1; i <= 3; i++){
        personalMovieDB.genres[i - 1] = prompt(`Ваш любимый жанр номер ${i}`);
    }
}
writeYourGenres(); // Вызов функции

// 5. Функция проверки приватности БД - 2-я часть задания
function showMyDB(hidden){
    if(!hidden){
        console.log(personalMovieDB); // Выводим главный объект программы
    }
}
showMyDB(personalMovieDB.private); // Вызов функции

Результат

Далее (см. код ниже) следует рефакторинг исходного кода и выполнение 2-ой и 3-ей части задания:

1. Первая часть задания. Из всех функций (из исходного кода) редактируется только метод start() следующим образом: переменная numberOfFilms уже не используется, так как ответ на 1-ый вопрос сразу заносится в свойство count объекта personalMovieDB.

2. Решение 2-ой части задания. Создается метод toggleVisibleMyDB, который переключает приватность/видимость БД. Метод toggleVisibleMyDB меняет значение свойства privat на противоположное: true <--> false.

3. Дополняется метод Жанров writeYourGenres в соответствии с условием - 3-я часть задания.

При этом используется стрелочная функция.

Запись (item, i) => {...} аналогична записи function(item, i) {...}

Рефакторинг кода + 2-я и 3-я часть задания


// 1-я часть задания - Перезапись функций, как методов объекта personalMovieDB
const personalMovieDB = {
    count: 0,
    movies: {},
    actors: {},
    genres: [],
    private: false,
// Метод start - Начало: первый вопрос...
    start: function() {
        personalMovieDB.count = +prompt('Сколько фильмов вы уже посмотрели?');
        // Проверка: на пустое поле для ввода ИЛИ на кнопку Отмена ИЛИ на НЕ число
        while (personalMovieDB.count == '' || personalMovieDB.count == null || isNaN(personalMovieDB.count)) {
            personalMovieDB.count = +prompt('Сколько фильмов вы уже посмотрели?');
        } 
    },
// Метод rememberMyFilms - Информация о фильмах
    rememberMyFilms: function() {
        for (let i = 0; i < 2; i++) {
            const a = prompt(`Один из последних просмотренных фильмов №_${i+1}`),
                  b = prompt('На сколько оцените его?');   
            /* Проверка на пустое поле для ввода ИЛИ на кнопку Отмена ИЛИ на количество символов */
            if (a != '' && b != '' && a != null && b != null && a.length < 50) {
                personalMovieDB.movies[a] = b; 
                console.log('done');
            }
            else {
                console.log('error');
                i--; 
            }
        }
    },
// Метод detectPersonalLevel - Анализ уровня Киномании
    detectPersonalLevel: function() {
        if (personalMovieDB.count < 10) {
            console.log('Просмотрено довольно мало фильмов');
        } else if (personalMovieDB.count > 10 && personalMovieDB.count < 30) {
            console.log('Вы классический зритель');
        } else if (personalMovieDB.count > 30) {
            console.log('Вы киноман');
        } else {
            console.log('Произошла ошибка');
        }
    },
// Метод showMyDB - проверка приватности БД и вывод главного Объекта программы
// Аргумент hidden - Свойство private: false или true
    showMyDB: function(hidden) {
        if(!hidden){
            console.log(personalMovieDB);
        }
    },
// 2-я часть задания - метод toggleVisibleMyDB
// Переключаем приватность/видимость БД
    toggleVisibleMyDB: function() {
        if(personalMovieDB.private){
            personalMovieDB.private = false;
        }
        else {
            personalMovieDB.private = true;
        }
    },
// 3-я часть задания - метод Жанров writeYourGenres
    writeYourGenres: function() {
        for (let i = 1; i <= 3; i++) {
            let genre = prompt(`Ваш любимый жанр номер ${i}`);
            // Проверка на пустое поле для ввода ИЛИ на кнопку Отмена
            if(genre == '' || genre == null){
                console.log('Вы ввели некорректные данные или не ввели их вовсе');
                i--;
            }
            else{
                personalMovieDB.genres[i - 1] = genre;
            }    
        }
        // Вывод любимых жанров №... - Метод forEach
        personalMovieDB.genres.forEach((item, i) => {
            console.log(`Любимый жанр ${i + 1} - это ${item}`);
        });
    }
};

Результат

Пример тестирования кода в консоли Браузера


// 1. Тестирование - метода Жанров - 3-я часть задания....
personalMovieDB.writeYourGenres();
2 Вы ввели некорректные данные или не ввели их вовсе
Любимый жанр 1 - это qwe
Любимый жанр 2 - это qwerty
Любимый жанр 3 - это asdf
// ...в результате в массиве жанров - 3 Элемента
personalMovieDB
{count: 0, movies: {…}, actors: {…}, genres: Array(3), private: false, …}

// 2. Тестирование метода showMyDB
// Т. к. значение свойства private: false - Метод выводит главный Объект программы
personalMovieDB.showMyDB(personalMovieDB.private)
{count: 0, movies: {…}, actors: {…}, genres: Array(3), private: false, …}
undefined

// 3. Тестирование метода toggleVisibleMyDB....
personalMovieDB.toggleVisibleMyDB();
undefined
// ...после этого меняется значение свойства private: true
personalMovieDB
{count: 0, movies: {…}, actors: {…}, genres: Array(3), private: true, …}
// Поэтому метод showMyDB - УЖЕ НЕ выводит главный Объект программы
personalMovieDB.showMyDB(personalMovieDB.private);
undefined

// ........ Дополнительно тестируем методы start() и detectPersonalLevel()
personalMovieDB.start();
undefined
personalMovieDB
{count: 21, movies: {…}, actors: {…}, genres: Array(3), private: true, …}

personalMovieDB.detectPersonalLevel();
Вы классический зритель
undefined

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

При этом, если в методе объекта personalMovieDB используется метод prompt, то в саммом окне браузера появляется окно для ввода данных.

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

Оптимизация кода для 3-ей части задания

Оптимизация кода для 3-ей части задания заключается в следующем: нужно сделать так, чтобы пользователь ввел сразу все жанры в виде одной строки, из которой формируется массив. Элементы массива сортируются в алфавитном порядке.


// 3-я часть задания - метод Жанров writeYourGenres
    writeYourGenres: function() {
        for (let i = 1; i < 2; i++) {
            let genre = prompt(`Введите ваши любимые жанры через пробел`).toLowerCase();
            // Метод toLowerCase() переводит строку в нижний регистр
            if(genre == '' || genre == null){
                console.log('Вы ввели некорректные данные или не ввели их вовсе');
                i--;
            }
            else{
                personalMovieDB.genres = genre.split(' '); // Формируем массив из строки
                personalMovieDB.genres.sort(); // Сортировка массива
            }    
        }
        // Вывод любимых жанров №... - Метод forEach
        personalMovieDB.genres.forEach((item, i) => {
            console.log(`Любимый жанр ${i + 1} - это ${item}`);
        });
    }

Результат

Пример тестирования кода в консоли Браузера


personalMovieDB.writeYourGenres();
Любимый жанр 1 - это боевик
Любимый жанр 2 - это вестерн
Любимый жанр 3 - это комедия
Любимый жанр 4 - это ужасы
undefined

1. Вопрос о жанрах задается один раз, но здесь все равно используется цикл. Сделано это для того, чтобы вернуть пользователя к вопросу, если он оставил пустым поле для ввода или нажал "Отмена".

2. Метод toLowerCase() - переводит строку в нижний регистр, чтобы метод sort() сортировал элементы массива без учета регистра.

3. Метод split - формирует массив из строки по указанному разделителю - это пробел.





Отзывы и комментарии:

Комментариев нет...

Оставить отзыв:

Ваше Имя:

Текст комментария:

Ответьте на вопрос:

Сколько дней в Високосном году?


Рунет - Часть 2
Практика часть 4 - Используем функции как методы объекта
9719
Условия if else - Конструкция switch case - Тернарный оператор
230
Циклы while и for - Операторы break и continue
278
Практика часть 2 – Циклы и Условия
621
Объявление функций – Стрелочные функции ES6
462
Методы и свойства строк и чисел - Метод substr - Индекс строки
144
Практика часть 3 - Используем функции
333
Что такое callback-функция - Аргумент другой функции
525
Свойства и методы объектов - Деструктуризация объектов ES6
850
Методы массивов - Перебор элементов массива - Псевдомассивы
813
Передача данных по ссылке и по значению – Клонирование объекта
197
Метод assign() – Копирование исходных объектов в целевой объект
162
Копирование массивов - Оператор spread
406
Прототипное Программирование - Прототип и Экземпляр Объекта
169
Свойство proto - Методы Object.create и Object.setPrototypeOf
433
Помощь сайту
Yandex-деньги/Ю-Money
410011236419322
Перевод на карту СБ
4276 1300 1671 5819
WebMoney
R711879515665 Z861169301432

Тематические публикации
Популярные заметки
Последние заметки