Javascript 的递归函数中的加法赋值未达到预期 运行
Addition assignment did not run as expected in Javascript's recursive functions
以下使用加法赋值的函数,当传递大于1的整数时,ans
的值总是变为1
let ans = 0;
function reduce(num){
if(num == 0){
return 0;
}
ans += reduce(num-1);
return 1;
}
reduce(5);
console.log(ans); // 1
但是当我先将递归结果保存到另一个变量时,函数运行正常(ans
将更改为num-1
)
let ans = 0;
function reduce(num){
if(num == 0){
return 0;
}
let tmp=reduce(num-1);
ans += tmp;
return 1;
}
reduce(5);
console.log(ans); // 4
这是怎么发生的?这是 Javascript 的特性还是环境中的错误?
我试过类似的 C 代码,它们的行为都一样
#include<stdio.h>
int reduce(int num);
int ans;
int main(){
ans = 0;
reduce(5);
printf("%d",ans); // 4
}
int reduce(int num){
if(num == 0){
return 0;
}
int tmp=reduce(num-1);
ans += tmp;
// ans += reduce(num-1);
return 1;
}
环境:
- 微软边缘 97.0.1072.55
- JavaScript V8 9.7.106.18
发生这种情况是因为在 JavaScript 中 ans += reduce(num-1)
被评估为:
ans = ans + reduce(num-1)
而不是:
ans = reduce(num-1) + ans;
(参见 ECMAScript 规范中的 (13.15.2) Runtime semantics: evaluation)。
所以 ans
在递归调用之前被 求值 ,并且 求值 值被用作加法的操作数。
您可以通过避免具有 side-effects. A pure 递归解决方案的函数来避免此类意外行为:
function reduce(num) {
if (num < 2) {
return 0;
}
return reduce(num-1) + 1;
}
let ans = reduce(5);
console.log(ans); // 4
以下使用加法赋值的函数,当传递大于1的整数时,ans
的值总是变为1
let ans = 0;
function reduce(num){
if(num == 0){
return 0;
}
ans += reduce(num-1);
return 1;
}
reduce(5);
console.log(ans); // 1
但是当我先将递归结果保存到另一个变量时,函数运行正常(ans
将更改为num-1
)
let ans = 0;
function reduce(num){
if(num == 0){
return 0;
}
let tmp=reduce(num-1);
ans += tmp;
return 1;
}
reduce(5);
console.log(ans); // 4
这是怎么发生的?这是 Javascript 的特性还是环境中的错误?
我试过类似的 C 代码,它们的行为都一样
#include<stdio.h>
int reduce(int num);
int ans;
int main(){
ans = 0;
reduce(5);
printf("%d",ans); // 4
}
int reduce(int num){
if(num == 0){
return 0;
}
int tmp=reduce(num-1);
ans += tmp;
// ans += reduce(num-1);
return 1;
}
环境:
- 微软边缘 97.0.1072.55
- JavaScript V8 9.7.106.18
发生这种情况是因为在 JavaScript 中 ans += reduce(num-1)
被评估为:
ans = ans + reduce(num-1)
而不是:
ans = reduce(num-1) + ans;
(参见 ECMAScript 规范中的 (13.15.2) Runtime semantics: evaluation)。
所以 ans
在递归调用之前被 求值 ,并且 求值 值被用作加法的操作数。
您可以通过避免具有 side-effects. A pure 递归解决方案的函数来避免此类意外行为:
function reduce(num) {
if (num < 2) {
return 0;
}
return reduce(num-1) + 1;
}
let ans = reduce(5);
console.log(ans); // 4