Это хвостовой вызов? (Javascript)

Предположим, у вас есть рекурсивная функция, такая как:

Blah.prototype.add = function(n) {
    this.total += n;
    this.children.forEach(function(child) {
        child.add(n);
    });
};

Это child.add() хвостовой вызов? Если нет, то можно ли так написать?

2 ответа

Решение

Да, это хвостовой вызов:

function(child) {
    child.add(n);
// ^ tail
}

И все же здесь нет ничего рекурсивного, потому что это не прямой рекурсивный вызов.

Также this.children.forEach(…) это хвостовой вызов в пределах add метод.

Тем не менее, вызов обратного вызова внутри нативного forEach метод, вероятно, не оптимизирован хвостовым вызовом (и все, кроме последнего, не может быть в любом случае). Вы можете заставить его переписать свою функцию

Blah.prototype.add = function(n) {
    "use strict";
    this.total += n;
    let l = this.children.length;
    if (!l--)
        return;
    for (let i=0; i<l; i++)
        this.children[i].add(n);
    this.children[i].add(n); // tail-recursion
};

Обратите внимание, что ни один из этих хвостовых вызовов не будет оптимизирован, если вы не return их результаты.

Оптимизированы ли хвостовые вызовы движков Javascript?

JavaScript в настоящее время не будет оптимизирован для этого

Другим вариантом будет батут https://taylodl.wordpress.com/2013/06/07/functional-javascript-tail-call-optimization-and-trampolines/

Другие вопросы по тегам