У меня есть этот класс
export class CurrentLanguageService {
currentLanguage(loggedUser: User): string {
if (sessionStorage.getItem(LanguageStorageKey) !== null) {
if (Object.keys(Languages).includes(sessionStorage.getItem(LanguageStorageKey))) {
return sessionStorage.getItem(LanguageStorageKey);
} else {
return Languages[Languages.nl];
}
} else {
if (loggedUser.language) {
return Languages[loggedUser.language];
} else {
return Languages[Languages.nl];
}
}
}
}
Вы увидите, что у меня так много условий, есть ли способ, которым кто-нибудь знает, что это правильное кодирование, спасибо
2 ответа
Я не думаю, что логика верна. Зачем возвращать язык по умолчанию, если есть язык, соответствующий ключу языкового хранилища, но не содержащийся в Object.keys
? Я бы подумал, что язык зарегистрированного пользователя будет лучшей альтернативой.
var language = sessionStorage.getItem(LanguageStorageKey);
if (language !== null && Object.keys(Languages).includes(language)) {
return language;
} else if (loggedUser.language) {
return Languages[loggedUser.language];
} else {
return Languages[Languages.nl];
}
Это упрощение возможно благодаря следующим моментам:
- Объединение двух условий в один оператор if с
&&
. Обратите внимание, что Java Script (и, следовательно, TypeScript) использует оценка короткого замыкания. Т.е. второе условие оценивается только в том случае, если первоеtrue
(на случай, если&&
). - Последовательное тестирование условий вместо использования вложенных операторов if.
- Возврат языка по умолчанию (nl) в одном месте из-за лучшей логики.
- Сохранение результата звонка
sessionStorage.getItem(LanguageStorageKey)
во временную переменную вместо трехкратного выполнения вызова. Это приводит не только к небольшому увеличению производительности, но и делает код более читабельным.
Украсить
Первое, что вам нужно сделать: применить рефакторинг. Извлечь переменную. Это сделает код чище и быстрее.
const storedLanguage = sessionStorage.getItem(LanguageStorageKey);
if (storedLanguage !== null) {
if (Object.keys(Languages).includes(storedLanguage)) {
return storedLanguage;
} else {
return Languages[Languages.nl];
}
} else {
…
}
После этого избавимся от if-s, применив Заменить вложенные условия на защитные предложения
const storedLanguage = sessionStorage.getItem(LanguageStorageKey);
if (storedLanguage !== null && Object.keys(Languages).includes(storedLanguage)) {
return storedLanguage;
}
if (loggedUser.language) {
return Languages[loggedUser.language];
}
return Languages[Languages.nl];
И теперь мы можем использовать Нулевое слияние оператор, чтобы упростить наш код
const storedLanguage = sessionStorage.getItem(LanguageStorageKey);
if (storedLanguage !== null && Object.keys(Languages).includes(storedLanguage)) {
return storedLanguage;
}
return Languages[loggedUser.language ?? Languages.nl];
Теперь я предлагаю использовать in
-синтаксис, чтобы сделать вещи короче:
if (storedLanguage !== null && storedLanguage in Languages) {
…
В некоторых стилях кода следующий трюк можно считать плохим. Обычно машинописный текст отказывает вам в выполнении проверки типа null in smth
, из-за набора текста. Но здесь он ошибается. Мы можем использовать ненулевой оператор утверждения
const storedLanguage = sessionStorage.getItem(LanguageStorageKey);
if (storedLanguage! in Languages) {
return storedLanguage;
}
return Languages[loggedUser.language ?? Languages.nl];
Тот же уровень абстракции
Давайте проясним ситуацию. Вы проверяете, что storedLanguage находится в перечислении. Построим для него служебную функцию
function keepIfInEnum<T>(
value: string,
enumObject: { [key: string]: T }
) {
if (Object.values(enumObject).includes((value as unknown) as T)) {
return (value as unknown) as T;
} else {
return undefined;
}
}
Теперь мы можем написать:
return keepIfInEnum(sessionStorage.getItem(LanguageStorageKey))
?? Languages[loggedUser.language ?? Languages.nl];