我有一个 JavaScript 函数,其 return 语句中有一个三元运算符。我不明白的是返回部分:
yell(n-1) + "a"
。我期待的结果是3a
,结果却是hiyaaaa
。这是为什么?
var ninja = {
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
};
ninja.yell(4); //returns hiyaaaa
yell(n-1)+"a"
使用稍低的 n
值再次调用该函数,并将 a
附加到递归调用返回的任何内容。在这种情况下,你会得到这条链:
ninja.yell(4)
yell(3)+"a"
(yell(2)+"a")+"a"
((yell(1)+"a")+"a")+"a"
(((yell(0)+"a")+"a")+"a")+"a"
((("hiy"+"a")+"a")+"a")+"a"
"hiyaaaa"
尽管如此,我个人会重写该函数:
ninja = {
yell: function(n) {return "hiy"+new Array(n+1).join("a");}
};
yell
是一个递归函数。当你用 4 调用它时,它会用 3 (4 - 1) 调用自身,3 (4 - 1) 又会用 2 (3 - 1) 调用自身,依此类推,只要 n
是 > 0
。
之所以可以这样调用
yell
,是因为编写代码的人写了一个命名函数表达式:
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
它的作用是创建一个名为
yell
的函数,并将其分配给对象 yell
上的 属性
ninja
。属性和函数碰巧具有相同的名称,但它们没有理由必须这样做,它可能是:
yell: function foo(n){
return n > 0 ? foo(n-1) + "a" : "hiy";
}
yell
(非限定符号)或上面示例中的 foo
位于函数范围内,因为它是函数的名称。
这里值得一提的是,命名函数表达式在 IE8 及更早版本上不能正常工作(尽管该特定示例仍然有效);更多:双重考虑
return n > 0 ? yell(n - 1) + "a" : "hiy";
yell(n - 1)
将在 before 与 "a"
连接起来执行。这意味着当它递归时(并且 n
变得更小),它最终将返回 "hiy"
以及之前调用中与其连接的其他 "a"
。
它是递归函数,调用自身直到n==0,工作正常。