моя функция обрезки своими руками не может вернуть правильный ответ, она возвращает неопределенный

#javascript #return #undefined

#javascript #Возврат #не определено

Вопрос:

Я пытаюсь создать функцию с именем «trim», чтобы удалить пробелы в начале и конце входной строки. (Я знаю, что String.prototype.trim может выполнять ту же работу, я просто практикую свой JS), но он возвращает «неопределенный», вы можете мне помочь?

 function trim(str) {
    if (str.charAt(0) === ' ') {
        str = str.slice(1);
        trim(str);
    } else if (str.charAt(str.length - 1) === ' ') {
        str = str.slice(0, -1);
        trim(str);
    } else {
        return str;
    }
}

console.log(trim('  ab c '));  

Комментарии:

1. вам нужно return trim(str) в первых двух блоках.

Ответ №1:

Вам нужно return из каждого места, где вы выполняете рекурсию, чтобы убедиться, что у вас есть обратные возвраты вплоть до стека к исходному вызывающему. Смотрите Фрагмент ниже.

 function trim(str) {
    if (str.charAt(0) === ' ') {
        str = str.slice(1);
        return trim(str);
    } else if (str.charAt(str.length - 1) === ' ') {
        str = str.slice(0, -1);
        return trim(str);
    } else {
        return str;
    }
}

console.log(trim('  ab c '));  

Еще немного контекста:

Каждый раз, когда вы вызываете trim изнутри тела trim функции, вы выполняете рекурсию. Если вы берете строку ' hello ' и вызываете trim as ( trim(' hello ') ) , происходит следующее:

  1. Вызов trim(' hello ') .
  2. Выполнено первое if условие — строка нарезается и trim('hello ') вызывается.
  3. Выполнено второе if условие — trim('hello') вызывается строка.
  4. if Условие не выполнено — else вводится блок `возвращается привет.

Итак, наш стек вызовов trim(' hello ') ==> trim('hello ') ==> trim('hello') . Однако в функции, как вы ее изначально написали, только последний вызов trim ( trim('hello') ) фактически возвращает значение предыдущему вызывающему — другие вызовы trim return nothing ( undefined ) . Чтобы убедиться, что возвращаемое значение передается обратно до исходного вызывающего объекта trim(' hello ') , вам нужно убедиться, что каждый раз, когда вы return повторяете результат рекурсии.

Комментарии:

1. Извините, меня смущает предложение «для того, чтобы убедиться, что у вас есть возврат всего пути вверх по стеку к исходному вызывающему», можете ли вы объяснить подробнее? Большое вам спасибо.

2. @toggler — Я предоставил еще немного контекста в ответе, пожалуйста, посмотрите, поможет ли это.

3. Думаю, теперь я понимаю. Это так же, как: function fn1(){ function fn2(){ return 1; } fn2(); } fn1(); //undefined прежде чем вы объяснили мне, я думал, что один «возврат» может проходить через цепочку вызывающих. Теперь я знаю, что был неправ. Еще раз спасибо!

4. Да, ваше резюме правильное — теперь оно у вас есть. Рад помочь. Если ответ был достаточно полезным, вы можете пометить его как «принятый», чтобы другие посетители знали, что он сработал для вас. Однако вы не обязаны делать это, если он каким-либо образом не оправдал ожиданий. Счастливого кодирования!

Ответ №2:

Вы возвращаете свое str else предложение only on . Вы должны возвращаться в каждом случае:

 function trim(str) {
    if (str.charAt(0) === ' ') {
        str = str.slice(1);
        trim(str);
    } else if (str.charAt(str.length - 1) === ' ') {
        str = str.slice(0, -1);
        trim(str);
    }
    return str;
}
  

Комментарии:

1. Я думаю, вы можете захотеть вернуться к этому ответу — если вы вызываете его с " hello " возвратом "hello " , а конечный пробел не обрезан.