Возвращаемое значение переключателя не определено - PullRequest
0 голосов
/ 07 января 2019

Когда я запускаю этот код из Notepad ++ через файл .html, вывод не распознает мои возвращаемые значения. Всегда выводит «undefined»

Я пытался поместить оператор return вне оператора switch, но это ничего не решило.

Редактировать: я включил код, который вызывает функцию, и исправил свои операторы if, основываясь на советах iCode.

// this came with the execrise
var sentinel = true

while (sentinel) {

    var month = prompt("Enter an integer from 1 to 12 inclusive, representing a month of the year");
    var request = prompt("Enter 1 if you want the name of the month, or enter 2 if you want the number of days in the month");

    if (months(month,request) == false) {
        // reset
        alert("Try again but enter the right stuff this time");

    } else {
        // output
        sentinel = false;

        if (request == 1) {

            console.log("Month number " + month + " is " + months(month,request));

        } else if (request == 2) {

            console.log("There are " + months(month,request) + " days in month number " + month);
        }
    }
}

// this is my edited code
function months(month,request) {
    if (!request || request < 1 || request > 2 || isNaN(request)) {
        return false;
    }
    if (!month || month < 1 || month > 12 || isNaN(month)) {
        return false;
    }

    var name;
    var numberDays;
    switch(month){
        case 1:
            if(request == 1){
                name = "January";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
            break;

        case 2:
            if(request == 1){
                name = "February";
                return name;
            }else{
                numberDays = "28";
                return numberDays;
            }
            break;

        case 3:
            if(request == 1){
                name = "March";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
            break;

        case 4:
            if(request == 1){
                name = "April";
                return name;
            }else{
                numberDays = "30";
                return numberDays;
            }
            break;

        case 5:
            if(request == 1){
                name = "May";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
            break;

        case 6:
            if(request == 1){
                name = "June";
                return name;
            }else{
                numberDays = "30";
                return numberDays;
            }
            break;

        case 7:
            if(request == 1){
                name = "July";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
            break;

        case 8:
            if(request == 1){
                name = "August";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
            break;

        case 9:
            if(request == 1){
                name = "September";
                return name;
            }else{
                numberDays = "30";
                return numberDays;
            }
            break;

        case 10:
            if(request == 1){
                name = "October";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
            break;

        case 11:
            if(request == 1){
                name = "November";
                return name;
            }else{
                numberDays = "30";
                return numberDays;
            }
            break;

        case 12:
            if(request == 1){
                name = "December";
                return name;
            }else{
                numberDays = "31";
                return numberDays;
            }
    }
}

                return false;
                    }
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

Я ожидаю, что результатом будет либо "Месяц № 1 - январь", либо "В месяце № 1 31 день"

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Объяснение неожиданного результата

Причина, по которой этот код возвращает undefined, заключается в том, что у вас есть необработанный регистр, который не имеет никакого возвращаемого значения. Каждый оператор if имеет свой собственный оператор else return false. Так что проблем там нет. Однако оператор switch не обрабатывает случай default. Это единственное место, которое не имеет возвращаемого значения, поэтому это должно быть проблемой.

Проблема возникает со строковым вводом для первого числа, поскольку он передает операторы , если , но не соответствует ни одному switch case.

console.log("'3' <= 12 //=>", '3' <= 12);
console.log("'3' >= 1 //=>",  '3' >= 1);

console.log("'3' == 3 //=>",  '3' == 3);
console.log("'3' === 3 //=>", '3' === 3);
//                ^ used for switch comparison

Это означает, что если вы запускаете свою функцию с такими входами, как months(3, 1) //=> "March", тогда как months('3', 1) //=> undefined. Сначала преобразуйте строку в целое число , чтобы правильно соответствовать одному из случаев. Это связано с тем, что в корпусах коммутаторов используется строгое сравнение .

После вашего редактирования это становится еще более понятным, поскольку мы можем видеть, откуда поступают данные.

var month = prompt("Enter an integer from 1 to 12 inclusive, representing a month of the year");
console.log(month, typeof(month));

Альтернативное решение

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

var monthsByNumber = {
    1:  { 1: "January",   2: "31" },
    2:  { 1: "February",  2: "28" },
    3:  { 1: "March",     2: "31" },
    4:  { 1: "April",     2: "30" },
    5:  { 1: "May",       2: "31" },
    6:  { 1: "June",      2: "30" },
    7:  { 1: "July",      2: "31" },
    8:  { 1: "August",    2: "31" },
    9:  { 1: "September", 2: "30" },
    10: { 1: "October",   2: "31" },
    11: { 1: "November",  2: "30" },
    12: { 1: "December",  2: "31" }
};

// This allows you to access the object attributes with either
//   a string or a number.
console.log("monthsByNumber[1] //=>",   monthsByNumber[1]);
console.log("monthsByNumber['1'] //=>", monthsByNumber['1']);

// Introducing this into the function would look something
//   like this.
function months(month, request) {
    // Normally you would define monthsByNumber here, but
    //   in this case I needed it in my demonstration
    //   above.
    
    // Use an empty object if it can't find the month.
    month = monthsByNumber[month] || {};
    return month[request];
}

// As you can see below this works with both numbers as well
//   as strings.
console.log("months(1, 1) //=>",     months(1, 1));
console.log("months('1', '2') //=>", months('1', '2'));
console.log("months(32, 1) //=>",    months(32, 1));

Приведенный выше код работает так же, как и следовало ожидать в текущей функции месяцев . Единственное изменение состоит в том, что undefined возвращается в случае неверного ввода. Что для меня имеет больше смысла, чем возвращение false. Если бы я попросил вас дать мне имя 14-го месяца, ответ «Я не знаю» лучше подходит, чем «Я не могу» . Вот где это примерно переводится.

Однако я бы предложил изменить наименование, поскольку ключи 1 и 2 для названия месяца и дней соответственно не очень очевидны. Я бы выбрал что-то вроде { name: 'January', days: '31' }, но для этого нужно изменить одну из двух вещей. Либо вход request также должен быть "name" или "days", другой вариант - преобразование ввода request в правильный формат. request = request == 1 ? "name" : "days". Кроме того, вы также можете рассмотреть возможность возврата нормального числа для дней вместо строки.

В JavaScript также есть Date встроенная функция, которую вы, возможно, захотите использовать для учета високосных лет и других вещей, но я не буду вдаваться в подробности об этом здесь .

0 голосов
/ 07 января 2019

@ Предположительно, я вижу, что вы, вероятно, пачкаете руки в JavaScript. Ваш образец выглядит как учебное упражнение. Повезло тебе. JS - забавный язык. Я взял ваш код и вставил его в JS скрипку и не получил никаких ошибок (хотя я видел предупреждения). Конечно, вы не предоставили код, который используете для вызова функции месяца. Таким образом, возможно, что вы получаете неопределенное значение из-за способа, которым вы вызываете или вызываете функцию month().

Как и предлагали другие, попробуйте уменьшить сложность кода, объединив некоторые из ваших операторов if с условными операторами AND (&&) или OR (||).

var sentinel = true
while (sentinel) {
	
var month = parseInt(prompt("Enter an integer from 1 to 12 inclusive, representing a month of the year"));
var request = parseInt(prompt("Enter 1 if you want the name of the month, or enter 2 if you want the number of days in the month"));
var result = months(month, request);

if (result == false) {
	// reset
	alert("Try again but enter the right stuff this time");

} else {
	// output
	sentinel = false;

	if (request === 1) {

		console.log("Month number " + month + " is " + result);

	} else if (request === 2) {

		console.log("There are " + result + " days in month number " + month);
	}
}
}

function months(month, request) {
	if (!request ||
		request < 1 ||
		request > 2) {
		return false;
	}
	if (!month ||
		month < 1 ||
		month > 12) {
		return false;
	}

	var name = "";
	var numberDays = 0;
	switch (month) {
		case 1:
			if (request === 1) {
				name = "January";
			} else {
				numberDays = 31;
			}
			break;
		// Repeat for case 2 - 12
		// ...
		
		// Include a default case though this should no longer get hit
		default:
			return -1;
			break;
	}
	if (request === 1) {
		return name;
	} else {
		return numberDays;
	}
}
   

 

Еще одним предложением было бы переместить объявление переменных name и numberDays , чтобы они находились над оператором switch. Компилятор JavaScript будет поднимать объявления переменных, используя ключевое слово var в верхней части функции. Если вы хотите использовать более современный JavaScript ( ES6 ), вы можете использовать ключевое слово let для объявления переменных в области видимости блока, как вы это сделали. Обратите внимание, что в старых версиях Internet Explorer вообще не поддерживается . Посетите сайт caniuse.com, чтобы определить совместимость браузера.

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

Я бы также проверил на равенство, используя тройное равенство === вместо ==. Тройное равенство (===) не будет выполнять преобразование типов, если, например, вы передадите «1» для месяца вместо 1. Таким образом, «1» == 1 является истинным; в то время как «1» === 1 ложно.

Еще один совет, который может вам помочь. При тестировании HTML / JavaScript / CSS вы можете использовать веб-сайт, такой как jsfiddle.net , jsbin.com или Plunker .

0 голосов
/ 07 января 2019

Упрощение вашего кода. Год необходим, чтобы точно узнать количество дней на февраль.

При создании новой даты (new Date(2019, 1, 0)) с параметром дня, установленным в 0, будет установлен последний день месяца.

function months(month, request = 1, year){
   if(year === undefined) year = (new Date()).getYear();
   const d = new Date(year, month, 0);
   return request === 1 ? d.toLocaleString('en-us', { month: 'long' }) : d.getDate();
}

const res0 = months(5);
const res1 = months(1,0);
const res2 = months(2,0);
const res3 = months(3,0);

console.log(res0, res1, res2, res3);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...