Поиск…
Синтаксис
- только return call () неявно, например, в функции стрелки или явно, может быть статусом вызова вызова
- function foo () {return bar (); } // вызов в бар - это вызов хвоста
- function foo () {bar (); } // bar не является хвостовым вызовом. Функция возвращает undefined, если возврат не указан
- const foo = () => bar (); // bar () - это хвостовой вызов
- const foo = () => (poo (), bar ()); // poo - не хвостовой вызов, bar - хвостовой вызов
- const foo = () => poo () && bar (); // poo - не хвостовой вызов, bar - хвостовой вызов
- const foo = () => bar () + 1; // bar не является хвостовым вызовом, так как требует возврата контекста + 1
замечания
TCO также известна как PTC (правильный хвостовой вызов), как это указано в спецификациях ES2015.
Что такое оптимизация хвостового звонка (TCO)
TCO доступна только в строгом режиме
Как всегда проверяйте реализации браузера и Javascript для поддержки любых языковых функций, а также с любой функцией или синтаксисом javascript, это может измениться в будущем.
Он предоставляет возможность оптимизировать рекурсивные и глубоко вложенные вызовы функций, устраняя необходимость нажимать состояние функции на глобальный стек фреймов и избегая необходимости переходить через каждую вызывающую функцию, возвращаясь непосредственно к начальной функции вызова.
function a(){
return b(); // 2
}
function b(){
return 1; // 3
}
a(); // 1
Без TCO вызов функции a()
создает новый фрейм для этой функции. Когда эта функция вызывает b()
кадр a()
помещается в стек фрейма и создается новый фрейм для функции b()
Когда b()
возвращается к кадру a()
a()
выводится из стека кадров. Он немедленно возвращается к глобальному фрейму и, таким образом, не использует ни одно из состояний, сохраняемых в стеке.
TCO признает, что вызов от a()
до b()
находится в хвосте функции a()
и, следовательно, нет необходимости толкать a()
в стек кадров. Когда b(0)
возвращается, а не возвращается к a()
он возвращается непосредственно к глобальному фрейму. Дальнейшая оптимизация путем устранения промежуточных этапов.
TCO позволяет рекурсивным функциям иметь неопределенную рекурсию, поскольку стек кадров не будет расти с каждым рекурсивным вызовом. Без рекурсивной функции TCO имела ограниченную рекурсивную глубину.
Примечание. TCO - это функция реализации механизма javascript, она не может быть реализована через транспилятор, если браузер не поддерживает его. Дополнительного синтаксиса в спецификации, требуемой для реализации TCO, нет, и поэтому существует опасение, что TCO может сломать сеть. Его выпуск в мире является осторожным и может потребовать установки флажков с браузером / двигателем для восприятия будущего.
Рекурсивные петли
Оптимизация Tail Call позволяет безопасно реализовать рекурсивные циклы без учета переполнения стека вызовов или накладных расходов растущего стека кадров.
function indexOf(array, predicate, i = 0) {
if (0 <= i && i < array.length) {
if (predicate(array[i])) { return i; }
return indexOf(array, predicate, i + 1); // the tail call
}
}
indexOf([1,2,3,4,5,6,7], x => x === 5); // returns index of 5 which is 4