Szukaj…
Składnia
- tylko call call () niejawnie, np. w funkcji strzałki lub jawnie, może być statystyką wywołania ogona
- function foo () {return bar (); } // wezwanie do paska jest wezwaniem ogona
- funkcja foo () {bar (); } // bar nie jest ogonem. Funkcja zwraca niezdefiniowaną, gdy nie zostanie podany zwrot
- const foo = () => bar (); // bar () to wywołanie ogonowe
- const foo = () => (poo (), bar ()); // kupa nie jest ogonem, bar jest ogonem
- const foo = () => poo () && bar (); // kupa nie jest ogonem, bar jest ogonem
- const foo = () => bar () + 1; // bar nie jest wywołaniem końcowym, ponieważ wymaga kontekstu, aby zwrócić +1
Uwagi
TCO jest również znany jako PTC (Proper Tail Call), jak to jest określone w specyfikacjach ES2015.
Co to jest optymalizacja ogona (TCO)
TCO jest dostępne tylko w trybie ścisłym
Jak zawsze sprawdzaj implementacje przeglądarki i JavaScript pod kątem obsługi dowolnych funkcji językowych, i podobnie jak w przypadku każdej funkcji lub składni javascript, może się to zmienić w przyszłości.
Zapewnia to sposób optymalizacji rekurencyjnych i głęboko zagnieżdżonych wywołań funkcji, eliminując potrzebę wypychania stanu funkcji na globalny stos ramek i unikając konieczności przechodzenia przez każdą funkcję wywołującą, wracając bezpośrednio do początkowej funkcji wywoływania.
function a(){
return b(); // 2
}
function b(){
return 1; // 3
}
a(); // 1
Bez TCO wywołanie a()
tworzy nową ramkę dla tej funkcji. Gdy ta funkcja wywołuje b()
ramka a()
jest wypychana na stos ramek i tworzona jest nowa ramka dla funkcji b()
Kiedy b()
powróci do a()
ramka a()
jest wyskakująca ze stosu ramek. Natychmiast powraca do ramki globalnej, a zatem nie używa żadnego ze stanów oprócz stosu.
TCO rozpoznaje, że wywołanie od a()
do b()
znajduje się na końcu funkcji a()
a zatem nie ma potrzeby wypychania stanu a()
na stos ramek. Kiedy b(0)
zwraca zamiast powrotu do a()
, wraca bezpośrednio do ramki globalnej. Dalsza optymalizacja poprzez wyeliminowanie etapów pośrednich.
TCO pozwala funkcjom rekurencyjnym na rekurencję na czas nieokreślony, ponieważ stos ramek nie rośnie z każdym wywołaniem rekurencyjnym. Bez funkcji rekurencyjnej TCO miała ograniczoną głębokość rekurencyjną.
Uwaga: TCO to funkcja implementacji silnika javascript, nie można jej zaimplementować za pomocą transpilatora, jeśli przeglądarka go nie obsługuje. Nie ma dodatkowej składni w specyfikacji wymaganej do implementacji TCO, dlatego istnieje obawa, że TCO może uszkodzić sieć. Jego publikacja na świecie jest ostrożna i może wymagać ustawienia flag specyficznych dla przeglądarki / silnika w przewidywalnej przyszłości.
Pętle rekurencyjne
Optymalizacja wywołania ogonowego umożliwia bezpieczne wdrażanie pętli rekurencyjnych bez obaw o przepełnienie stosu wywołań lub obciążenie rosnącym stosem ramek.
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