function f(x) {
return g(x)
}
// 情况一
function f(x){
let y = g(x);
return y;
}
// 情况二
function f(x){
return g(x) + 1;
}
[f(x)] => [g(x)]
[f(x)] => [1 + g(x)]
0, 1, 1, 2, 3, 5, 8, 13, 21, ...
function fibonacci(n) {
if (n === 0) return 0
if (n === 1) return 1
return fibonacci(n - 1) + fibonacci(n - 2)
}
[fibonacci(5)] [fibonacci(4) + fibonacci(3)] [(fibonacci(3) + fibonacci(2)) + (fibonacci(2) + fibonacci(1))] [((fibonacci(2) + fibonacci(1)) + (fibonacci(1) + fibonacci(0))) + ((fibonacci(1) + fibonacci(0)) + fibonacci(1))] [fibonacci(1) + fibonacci(0) + fibonacci(1) + fibonacci(1) + fibonacci(0) + fibonacci(1) + fibonacci(0) + fibonacci(1)] [1 + 0 + 1 + 1 + 0 + 1 + 0 + 1] 5
function fibonacciTail(n, a = 0, b = 1) {
if (n === 0) return a
return fibonacciTail(n - 1, b, a + b)
}
fibonacciTail(5) === fibonacciTail(5, 0, 1) fibonacciTail(4, 1, 1) fibonacciTail(3, 1, 2) fibonacciTail(2, 2, 3) fibonacciTail(1, 3, 5) fibonacciTail(0, 5, 8) => return 5
function fibonacciLoop(n, a = 0, b = 1) {
while (n--) {
[a, b] = [b, a + b]
}
return a
}
function trampoline(f) {
while (f && f instanceof Function) {
f = f()
}
return f
}
function fibonacciFunc(n, a = 0, b = 1) {
if (n > 0) {
[a, b] = [b, a + b]
return fibonacciFunc.bind(null, n - 1, a, b)
} else {
return a
}
}
trampoline(fibonacciFunc(5)) // return 5
function tailCallOptimize(f) {
let value,
active = false
const accumulated = []
return function accumulator() {
accumulated.push(arguments)
if (!active) {
active = true
while (accumulated.length) {
value = f.apply(this, accumulated.shift())
}
active = false
return value
}
}
}
const fibonacciTail = tailCallOptimize(function(n, a = 0, b = 1) {
if (n === 0) return a
return fibonacciTail(n - 1, b, a + b)
})
fibonacciTail(5) // return 5
const a = x => x ? f() : g()
const a = x => {
if (x) {
return f()
} else {
return g()
}
}
const a = () => f() || g()
const a = () => {
const result = f()
if (result) {
return result
} else {
return g()
}
}
const a = () => f() && g()
const a = () => {
const result = f()
if (!result) {
return result
} else {
return g()
}
}
const a = () => (f(), g())
const a = () => {
f()
return g()
}
function foo() {
bar()
}
function foo() {
bar()
return undefined
}
function factorial(n, acc = 1) {
if (n === 1) {
return acc;
}
return continue factorial(n - 1, acc * n)
}
let factorial = (n, acc = 1) => continue
n == 1 ? acc
: factorial(n - 1, acc * n);
// or, if continue is an expression form:
let factorial = (n, acc = 1) =>
n == 1 ? acc
: continue factorial(n - 1, acc * n);
// # sigil, though it's already 'claimed' by private state.
#function() { /* all calls in tail position are tail calls */ }
// Note that it's hard to decide how to readably sigil arrow functions.
// This is probably most readable.
() #=> expr
// This is probably most in line with the non-arrow sigil.
#() => expr
// rec sigil similar to async functions
rec function() { /* likewise */ }
rec () => expr
function () { !return expr }
// It's a little tricky to do arrow functions in this method.
// Obviously, we cannot push the ! into the expression, and even
// function level sigils are pretty ugly.
// Since ! already has a strong meaning, it's hard to read this as
// a tail recursive function, rather than an expression.
!() => expr
// We could do like we did for # above, but it also reads strangely:
() !=> expr
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有