Как вернуть результат функции внутри функции

Есть код, который удаляет пробелы вначале и в конце строки:

var str = prompt("Введите любое значение");
function trim(x) {
    let l = 0,
    r = str.length - 1;
    if (str[l] !== " " && str[r] !== " ") {
        console.log("no spaces");
        return str;
    } else {
        for (let i = l; i <= r; i++) {
            if (str[i] === " ") l++;
            else break;
        }
        function abc() {
            if (str[l - 1] === " ") {
                console.log(
                    "string has only spaces or spaces has deleted"
                );
                return "hello";
            }
        }
        abc(str);
        for (let q = r; q >= 0; q--) {
            if (str[r] === " ") r--;
        }
        return str.slice(l, r + 1);
    }
}
var ost = trim(str);
alert(`${"<"}` + ost + `${">"}`);

я хочу сделать так, чтобы при вводе пустой строки второй цикл пропускался и сразу выводился результат (return str.slice(l, r + 1);)

для этого я написал функцию:

function abc() {
    if (str[l - 1] === " ") {
        console.log(
            "string has only spaces or spaces has deleted"
        );
        return "hello";
    }
}
abc(str);

написал hello в качестве проверки. Но результата нет. Как можно это решить? (p.s. я новичок в Js)


Ответы (2 шт):

Автор решения: Arseni Mourzenko
[...]
const hello = abc(str);
if (hello) {
    return hello;
}

Несколько советов:

  • Не используйте var. Он злой и кусается.
  • Функции внутри других функций, вещь не то, что редкая, но необычная. В вашем случае, я не вижу не одной причины, по которой она должна быть внутри.
  • Используйте функции для того, чтобы разбить уж на логичные части. Блок кода, который вы привели, слишком сложный.
  • Названия переменных должны чаще всего о чем-то говорить о самих переменных. l, и r не очень удачный выбор.
  • Что такого плохого в уже существующей функции trim?

Следуя этим советам, и базируясь на коде, который вы привели в комментариях ниже, получаем следующее:

function ltrim(text) {
    const length = text.length;
    for (let i = 0; i < length; ++i) {
        if (text[i] !== " ") {
            return text.slice(i);
        }
    }

    return "";
}

function rtrim(text) {
    for (let i = text.length - 1; i >= 0; --i) {
        if (text[i] !== " ") {
            return text.slice(0, i + 1);
        }
    }

    return "";
}

function trim(text) {
    return rtrim(ltrim(text));
}

["abc", "  abc  ", "abc  def", "  abc  def  ", "   "].forEach(
    x => console.log(`<${x}> -> <${trim(x)}>`));

Результат:

<abc> -> <abc>
<  abc  > -> <abc>
<abc  def> -> <abc  def>
<  abc  def  > -> <abc  def>
<   > -> <>

Минус этого кода: он совсем не оптимальный. Пробегать текст два раза, не самая лучшая вещь. Но оставим оптимизацию для отдельного вопроса.

→ Ссылка
Автор решения: Leonid

В родной str.trim() удаляются все пробельные символы, а не только пробел. Регулярка с простой логикой: либо вернуть последовательность из хотя бы одного непробельного символа \S, любого количества любых символов ., хотя бы одного непробельного символа. Или хотя бы один непробельный символ. Если совпадений не нашлось, то возвращается пустая строка.

function trim(text){
    let match = text.match(/(\S+.*\S+|\S+)/);
    return match ? match[1] : "";
}

let result = ["  lj", "sd lf  ", "lj ", "sl     ", "s ld ld   ", "l", "", "  "].map(str => trim(str));

console.log(result);

Это выражение ближе к вашей функции: из строки удаляются все пробельные символы примыкающие к началу строки или примыкающие к концу строки.

function trim(text){
    return text.replace(/^\s+|\s+$/, '');
}

let result = ["  lj", "sd lf  ", "lj ", "sl     ", "s ld ld   ", "l", "", "  ", "lsd"].map(str => trim(str));

console.log(result);

→ Ссылка