<pre class="de1">
<span class="kw1">function tco<span class="br0">(f<span class="br0">) <span class="br0">{
<span class="kw1">var value<span class="sy0">;
<span class="kw1">var active <span class="sy0">= <span class="kw2">false<span class="sy0">;
<span class="kw1">var accumulated <span class="sy0">= <span class="br0">[<span class="br0">]<span class="sy0">;
<span class="kw1">return <span class="kw1">function accumulator<span class="br0">(<span class="br0">) <span class="br0">{
accumulated.<span class="me1">push<span class="br0">(arguments<span class="br0">)<span class="sy0">;
<span class="kw1">if <span class="br0">(<span class="sy0">!active<span class="br0">) <span class="br0">{
active <span class="sy0">= <span class="kw2">true<span class="sy0">;
while <span class="br0">(accumulated.<span class="me1">length<span class="br0">) <span class="br0">{
value <span class="sy0">= f.<span class="me1">apply<span class="br0">(<span class="kw1">this<span class="sy0">, accumulated.<span class="me1">shift<span class="br0">(<span class="br0">)<span class="br0">)<span class="sy0">;
<span class="br0">}
active <span class="sy0">= <span class="kw2">false<span class="sy0">;
<span class="kw1">return value<span class="sy0">;
<span class="br0">}
<span class="br0">}
<span class="br0">}
<span class="co1">//这种方式确实有点奇怪,但的确没有改动很多源码,只是以直接量的形式使用tco函数包裹源码
<span class="kw1">var sum <span class="sy0">= tco<span class="br0">(<span class="kw1">function<span class="br0">(x<span class="sy0">, y<span class="br0">) <span class="br0">{
<span class="kw1">if <span class="br0">(y <span class="sy0">> <span class="nu0">0<span class="br0">) <span class="br0">{
<span class="kw1">return sum<span class="br0">(x <span class="sy0">+ <span class="nu0">1<span class="sy0">, y <span class="sy0">- <span class="nu0">1<span class="br0">)
<span class="br0">}
<span class="kw1">else <span class="br0">{
<span class="kw1">return x
<span class="br0">}
<span class="br0">}<span class="br0">)<span class="sy0">;
sum<span class="br0">(<span class="nu0">1<span class="sy0">, <span class="nu0">10<span class="br0">) <span class="co1">// => 11
sum<span class="br0">(<span class="nu0">1<span class="sy0">, <span class="nu0">100000<span class="br0">) <span class="co1">// => 100001 没有造成栈溢出