以下是两个因子实现from this site:
尾调优化(TCO):
function fact(n) {
return tail_fact(n,1) ;
}
function tail_fact(n,a) {
if (n == 0)
return a ;
else
return tail_fact(n-1,n*a) ;
}
在延续式编程(回调)中重写的那个:
function fact(n,ret) {
tail_fact(n,1,ret) ;
}
function tail_fact(n,a,ret) {
if (n == 0)
ret(a) ;
else
tail_fact(n-1,n*a,ret) ;
}
似乎教程建议第二个版本也是TCO,但第二个版本返回的最后一个是undefined
,并且根据this tutorial,它的调用不在尾部位置。
然而,似乎这里根本没有使用return
,因此不需要在堆栈上创建一个带有要返回的地址的新帧。这是第二次实施TCO的原因吗?
答案 0 :(得分:2)
--harmony_tailcalls
的Node7并不认为第二个对TCO有效,但TCO在V8中没有100%完成(因此落后于运行时标志)。
Axel Rauschmayer says no, it's not a tail call,因为隐含return undefined
;在它之后:
以下代码中的函数调用
bar()
不在尾部位置:function foo() { bar(); // this is not a tail call in JS }
原因是
foo()
的最后一个操作不是函数调用bar()
,而是(隐式)返回undefined
。换句话说,foo()
的行为如下:function foo() { bar(); return undefined; }
来电者可以依赖
foo()
始终返回undefined
。如果bar()
要返回foo()
的结果,由于尾调用优化,则会改变foo的行为。
换句话说,在foo
的末尾,我们无法跳转到bar
,因为bar
可能会发出return
的值undefined
除了foo
之外,undefined
根本不会返回任何值(因此调用它会保证产生bar
)。当我们致电bar
说'#34}但不要返回bar
时,某事必须留下(至少现在) 。值#&34;那东西是堆栈框架。
理论上,JavaScript引擎可以在调用bar
时传递某种标志,告诉自己丢弃任何值 <div id="googlemaps"></div>
<div id="contactform">
<form>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="form-group">
<input type="text" class="form-control input-lg" id="firstname" placeholder="First Name">
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="form-group">
<input type="text" class="form-control input-lg" id="lastname" placeholder="Last Name">
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="form-group">
<input type="text" class="form-control input-lg" id="email" placeholder="Email">
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="form-group">
<textarea class="form-control" rows="3" placeholder="Message"></textarea>
</div>
</div>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<button type="submit" class="btn btn-default btn-lg btn-block">SEND MESSAGE</button>
</div>
</div>
</form>
</div>
返回,从而在这种情况下允许TCO,但我没有看到规范中的任何内容。