Ответ 1
Определить массив, затем получить по индексу.
var months = ['January', 'February', ...];
var month = months[mm - 1] || '';
Есть ли способ записать это на меньшее количество строк, но все же легко читается?
var month = '';
switch(mm) {
case '1':
month = 'January';
break;
case '2':
month = 'February';
break;
case '3':
month = 'March';
break;
case '4':
month = 'April';
break;
case '5':
month = 'May';
break;
case '6':
month = 'June';
break;
case '7':
month = 'July';
break;
case '8':
month = 'August';
break;
case '9':
month = 'September';
break;
case '10':
month = 'October';
break;
case '11':
month = 'November';
break;
case '12':
month = 'December';
break;
}
Определить массив, затем получить по индексу.
var months = ['January', 'February', ...];
var month = months[mm - 1] || '';
как вообще не использовать массив:)
var objDate = new Date("10/11/2009"),
locale = "en-us",
month = objDate.toLocaleString(locale, { month: "long" });
console.log(month);
// or if you want the shorter date: (also possible to use "narrow" for "O"
console.log(objDate.toLocaleString(locale, { month: "short" }));
в соответствии с этим ответом Получить имя месяца из Даты от David Storey
Попробуйте следующее:
var months = {'1': 'January', '2': 'February'}; //etc
var month = months[mm];
Обратите внимание, что mm
может быть целым числом или строкой, и оно все равно будет работать.
Если вы хотите, чтобы несуществующие ключи привели к пустой строке ''
(вместо undefined
), добавьте следующую строку:
month = (month == undefined) ? '' : month;
Вместо этого вы можете создать массив и найти имя месяца:
var months = ['January','February','March','April','May','June','July','August','September','October','November','December']
var month = months[mm-1] || '';
См. ответ от @CupawnTae для рационального кода || ''
Будьте осторожны!
Вещь, которая должна немедленно вызвать сигнальные колокола, - это первая строка: var month = '';
- почему эта переменная инициализируется пустой строкой, а не null
или undefined
? Это может быть просто привычка или копировать/вставлять код, но если вы не знаете, что это точно, небезопасно игнорировать его при рефакторинге кода.
Если вы используете массив имен месяцев и меняете свой код на var month = months[mm-1];
, вы меняете поведение, потому что теперь для чисел вне диапазона или нечисловых значений month
будет undefined
. Вы можете знать, что это нормально, но есть много ситуаций, когда это было бы плохо.
Например, предположим, что ваш switch
находится в функции monthToName(mm)
, и кто-то вызывает вашу функцию следующим образом:
var monthName = monthToName(mm);
if (monthName === '') {
alert("Please enter a valid month.");
} else {
submitMonth(monthName);
}
Теперь, если вы перейдете на использование массива и вернетесь monthName[mm-1]
, вызывающий код больше не будет функционировать так, как предполагалось, и он будет отправлять значения undefined
, когда он должен отображать предупреждение. Я не говорю, что это хороший код, но если вы точно не знаете, как используется код, вы не можете делать предположения.
Или, может быть, исходная инициализация была там, потому что какой-то код далее по строке предполагает, что month
всегда будет строкой и что-то вроде month.length
- это приведет к тому, что исключение будет выбрано за неверные месяцы и потенциально убить вызов script полностью.
Если вы знаете весь контекст - например, это все ваш собственный код, и никто другой никогда не будет использовать его, и вы доверяете себе, не забывайте, что вы сделали изменение когда-нибудь в будущем - может быть безопасно изменить такое поведение, как это, но soooo многие ошибки возникают из такое предположение, что в реальной жизни вам намного лучше защищать и/или документировать поведение.
Ответ Wasmoo исправляет (EDIT: теперь исправлены и другие ответы, в том числе принятые) - вы можете использовать months[mm-1] || ''
или если вы предпочли бы сделать это более очевидным с первого взгляда, что происходит, что-то вроде:
var months = ['January', 'February', ...];
var month;
if (mm >= 1 && m <= 12) {
month = months[mm - 1];
} else {
month = ''; // empty string when not a valid month
}
Для полноты я хотел бы дополнить текущие ответы. В принципе, вы можете опустить ключевое слово break
и напрямую вернуть соответствующее значение. Эта тактика полезна, если значение не может быть сохранено в предварительно вычисленной справочной таблице.
function foo(mm) {
switch(mm) {
case '1': return 'January';
case '2': return 'February';
case '3': return 'March';
case '4': return 'April';
// [...]
case '12': return 'December';
}
return '';
}
Еще раз, используя справочную таблицу или функции даты, более лаконично и субъективно лучше.
Вы можете сделать это с помощью массива:
var months = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December'];
var month = months[mm - 1] || '';
Здесь другой параметр, который использует только одну переменную и по-прежнему применяет значение по умолчанию ''
, когда mm
находится вне диапазона.
var month = ['January', 'February', 'March',
'April', 'May', 'June', 'July',
'August', 'September', 'October',
'November', 'December'
][mm-1] || '';
Вы можете записать его как выражение вместо коммутатора, используя условные операторы:
var month =
mm == 1 ? 'January' :
mm == 2 ? 'February' :
mm == 3 ? 'March' :
mm == 4 ? 'April' :
mm == 5 ? 'May' :
mm == 6 ? 'June' :
mm == 7 ? 'July' :
mm == 8 ? 'August' :
mm == 9 ? 'September' :
mm == 10 ? 'October' :
mm == 11 ? 'November' :
mm == 12 ? 'December' :
'';
Если вы еще не видели закодированных условных операторов, прежде чем это может показаться трудным для чтения вначале. Запись его в виде выражения делает один аспект еще более простым, чем исходный код; ясно, что целью кода является присвоение переменной переменной month
.
Основываясь на ответа Cupawn Tae, я бы сократил его до:
var months = ['January', 'February', ...];
var month = (mm >= 1 && mm <= 12) ? months[mm - 1] : '';
В качестве альтернативы, да, я ценю, менее читаем:
var month = months[mm - 1] || ''; // as mentioned further up
var getMonth=function(month){
//Return string to number.
var strMonth = ['January', 'February', 'March',
'April', 'May', 'June', 'July',
'August', 'September', 'October',
'November', 'December'
];
//return number to string.
var intMonth={'January':1, 'February':2, 'March':3,
'April':4, 'May':5, 'June':6, 'July':7,
'August':8, 'September':9, 'October':10,
'November':11, 'December':12
};
//Check type and return
return (typeof month === "number")?strMonth[month-1]:intMonth[month]
}
Как и @vidriduch, я хотел бы подчеркнуть важность i20y ( "интернационализма" ) кода в сегодняшнем контексте и предложить следующее сжатое и надежное решение вместе с унитарным тестом.
function num2month(month, locale) {
if (month != Math.floor(month) || month < 1 || month > 12)
return undefined;
var objDate = new Date(Math.floor(month) + "/1/1970");
return objDate.toLocaleString(locale, {month: "long"});
}
/* Test/demo */
for (mm = 1; mm <= 12; mm++)
document.writeln(num2month(mm, "en") + " " +
num2month(mm, "ar-lb") + "<br/>");
document.writeln(num2month("x", "en") + "<br/>");
document.writeln(num2month(.1, "en") + "<br/>");
document.writeln(num2month(12.5, "en" + "<br/>"));
Я бы выбрал решение wasmoo, но настроил его следующим образом:
var month = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
][mm-1] || '';
Это тот же самый код, действительно, но по-разному с отступом, который IMO делает его более читаемым.