Охватывает ли ES6 Tail Call Optimization генераторы?
Охватывает ли поддержка ES6 оптимизации хвостовых вызовов хвостовыми вызовами в генераторах?
Предположим, у меня есть этот генератор для целых чисел>= 0:
var nums = function* (n) {
n = n || 0;
yield n;
yield* nums(n + 1);
};
В настоящее время в Chrome и Firefox он добавляет уровень стека к каждому рекурсивному вызову и в конечном итоге приводит к ошибке "Превышен максимальный размер стека вызовов". Будет ли это происходить после полной реализации ES6?
(Я знаю, что могу написать вышеупомянутый генератор итеративно и не столкнуться с ошибкой. Мне просто интересно, будет ли TCO заботиться о рекурсивно определенных генераторах.)
1 ответ
Когда выполняется вызов функции, в соответствии с разделом Оценка вызова функции,
- Пусть tailCall будет IsInTailPosition (thisCall)
- Вернуть? EvaluateCall (func, ref, arguments, tailCall)
Вызов будет оцениваться на основе IsInTailPosition
результат. И если если мы проверим IsInTailPosition
,
- Если body - это FunctionBody объекта GeneratorBody, вернуть false.
Таким образом, если тело функции является генератором, оптимизация Tail Call не будет выполнена.