开关返回值未定义

时间:2019-01-07 19:27:06

标签: javascript function switch-statement return-value

当我通过.html文件从Notepad ++运行此代码时,输​​出无法识别我的返回值。它总是输出“未定义”

我尝试将return语句放在switch语句之外,但是它没有解决任何问题。

编辑:我包括了调用该函数的代码,并根据iCode的提示修复了if语句。

// 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月”或“第1月有31天”

3 个答案:

答案 0 :(得分:0)

您的代码的简化。必须正确地输入年份以获取2月的天数。

使用day参数设置为0创建新日期(new Date(2019, 1, 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);

答案 1 :(得分:0)

意外结果的说明

此代码返回undefined的原因是因为您有一个未处理的案例,没有任何返回值。每个 if 语句都带有自己的 else 语句return false。因此,那里没有问题。但是, switch 语句不能处理default情况。这是唯一没有返回值的地方,所以一定是问题所在。

第一个数字的字符串输入会出现问题,因为它传递了 if 语句,但与任何 switch 情况都不匹配。

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等。 Convert the string to an integer首先要正确匹配其中一种情况。这是由于switch cases use a strict comparison

在您进行编辑之后,这一点变得更加清晰,因为我们可以看到数据来自何处。

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));

上面的代码与您在当前 months 函数中所期望的功能相同。唯一的变化是,如果输入无效,则返回undefined。对我来说,比返回false更有意义。如果我要您给我第14个月的名字,那么答案“我不知道” “我不能” 更合适。大致翻译成哪个。

但是我建议更改命名方式,因为分别表示月份名称和日期的键12不太明显。我会选择类似{ name: 'January', days: '31' }之类的东西,但这需要更改以下两项之一。 request输入也应该是"name""days",另一个选择是将request输入转换为正确的格式。 request = request == 1 ? "name" : "days"。此外,您可能还需要考虑返回几天的正常数字而不是字符串。

JavaScript还有一个Date对象内置函数,您可能想用它来解释leap年和其他情况,但是我在这里不做详细介绍。

答案 2 :(得分:0)

@Prospective,我发现您可能正在用JavaScript弄脏手。您的样本似乎是一种学习练习。对你有益。 JS是一种有趣的语言。我获取了您的代码并将其粘贴到JS fiddle中,但没有收到任何错误(尽管我确实看到了警告)。当然,您没有提供用于调用month函数的代码。因此,可能由于调用或调用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根本不support let。请访问caniuse.com网站,确定浏览器的兼容性。

尽管不是必需的,另一个好的做法是为您返回的变量提供默认值。然后,在检查函数的返回值时,可以检查默认值。

我还将使用三重等于===而不是==来检查是否相等。例如,如果您在月份中输入“ 1”而不是1,则三重等于(===)将不会进行类型转换。因此,“ 1” == 1为true;而“ 1” === 1为假。

另一个提示可能会对您有所帮助。在测试HTML / JavaScript / CSS时,可以使用在线网站,例如jsfiddle.netjsbin.comPlunker