Функция, очевидно, хочет создать строку из строчных и прописных букв, в зависимости от вводимых символов. Когда они являются одним из dhntz
, на выходе выдается заглавная буква (начиная с кода ASCII 65), а для всех остальных букв - строчная буква (начиная с кода ASCII 97). Не-буквы остаются нетронутыми.
Если бы условия if
были поменяны местами, он мог бы использовать [a-z]
. Вот так:
if (/[zdhnt]/.test(str[i])) {
newStr += String.fromCharCode(((str[i].charCodeAt(0) - 18) % 26) + 65);
}
else if (/[a-z]/.test(str[i])) {
newStr += String.fromCharCode(((str[i].charCodeAt(0) - 18) % 26) + 97)
}
Но кодер выбрал другой путь и сначала проверил наличие букв, которые не являются специальными символами. Таким образом, это объединение диапазонов, которое эквивалентно более длинному:
/[a-c]|[e-g]|[i-m]|[o-s]|[u-y]/
Жаль, что в коде есть некоторое повторение кода при использовании выражения String.fromCharCode
.
То же самое может быть достигнуто так:
function LetterChanges(str) {
return str.trim().toLowerCase().replace(/([zdhnt])|[a-z]/g, (m, toCapital) =>
String.fromCharCode(((m.charCodeAt(0) - 18) % 26) + (toCapital ? 65 : 97))
);
}
console.log(LetterChanges("abcdefghijk"));
Здесь метод replace
используется с аргументом обратного вызова. Соответствующий символ будет аргументом m
, и если совпадение было в группе захвата (([zdhnt])
), то toCaptital
также будет тем же значением, в противном случае оно будет пустым. Тройное выражение делает все остальное.