为什么这个函数 return ['y','e','s']?
why does this function return ['y','e','s']?
谁能给我解释一下这个函数 return ['y','e','s'] 而不仅仅是字符串 'yes' ???
num 的值首先将是 8 然后 else 条件将起作用然后 num 将是 [5,6,7] 并且 else 条件将再次起作用然后 num 最终变成一个空数组 [] 它将满足 if 条件然后它应该 return 'yes' 但事实并非如此!?
function ABC(num, ...rest) {
if (num < 5) {
return 'yes';
} else {
return [...ABC(rest)];
}
};
console.log(ABC(8, 5, 6, 7));
当num < 5
它returns yes
.
如果第一个参数没有触发,yes
将返回给:
return [...ABC(rest)];
它会在哪里传播并放入一个数组中。
当你进行递归调用时,你 [...ABC(rest)]
首先运行该函数,然后将 其结果 传播到一个数组中。如果我们添加一个中间变量,这会更清楚:
let recursive_result = ABC(rest);
return [...recursive_result];
您打算首先将 rest
传播到函数的参数中,然后直接 return 结果:
let recursive_result = ABC(...rest);
return recursive_result;
解决这个问题,我们又发现了一个问题,就是一旦数组为空,函数就会被无参调用,num
会变成undefined
,仍然不是"小于 5"。这意味着永远不会到达 if
语句,我们将永远递归(直到你的 JS 引擎放弃并引发错误)。
显式检测undefined
,我们得到您期望的结果:
function ABC(num, ...rest) {
if (num < 5 || typeof num == 'undefined' ) {
return 'yes';
} else {
return ABC(...rest);
}
};
console.log(ABC(8, 5, 6, 7));
如果你加几个 console.log
就更清楚了:
function ABC(num, ...rest) {
console.log(`num=`, num, ", rest=", rest)
if (num < 5) {
console.log(`returning 'yes'`)
return 'yes';
} else {
console.log(`returning [...ABC(${rest})]`)
return [...ABC(rest)];
}
};
console.log(ABC(8, 5, 6, 7));
- 运行 1: num=8 , rest=[5, 6, 7]
所以它进入 else
和 returns [...ABC([5, 6, 7])]
。只有一个参数,一个数组。所以在 运行 2:
- 运行 2 : num=[5, 6, 7] , rest= []
[5, 6, 7] < 5
?错误的。所以它再次进入 else
。它returns [...ABC([])]
.
- 运行 3 : num=[] , rest= []
[] < 5
?真的,很奇怪。所以 ABC([])
returns 'yes'
.
但是这个 'yes'
被返回 到前一个函数调用 ,即 [...ABC([])]
,它变成 [...'yes']
,它是 ['y', 'e', 's']
.
谁能给我解释一下这个函数 return ['y','e','s'] 而不仅仅是字符串 'yes' ??? num 的值首先将是 8 然后 else 条件将起作用然后 num 将是 [5,6,7] 并且 else 条件将再次起作用然后 num 最终变成一个空数组 [] 它将满足 if 条件然后它应该 return 'yes' 但事实并非如此!?
function ABC(num, ...rest) {
if (num < 5) {
return 'yes';
} else {
return [...ABC(rest)];
}
};
console.log(ABC(8, 5, 6, 7));
当num < 5
它returns yes
.
如果第一个参数没有触发,yes
将返回给:
return [...ABC(rest)];
它会在哪里传播并放入一个数组中。
当你进行递归调用时,你 [...ABC(rest)]
首先运行该函数,然后将 其结果 传播到一个数组中。如果我们添加一个中间变量,这会更清楚:
let recursive_result = ABC(rest);
return [...recursive_result];
您打算首先将 rest
传播到函数的参数中,然后直接 return 结果:
let recursive_result = ABC(...rest);
return recursive_result;
解决这个问题,我们又发现了一个问题,就是一旦数组为空,函数就会被无参调用,num
会变成undefined
,仍然不是"小于 5"。这意味着永远不会到达 if
语句,我们将永远递归(直到你的 JS 引擎放弃并引发错误)。
显式检测undefined
,我们得到您期望的结果:
function ABC(num, ...rest) {
if (num < 5 || typeof num == 'undefined' ) {
return 'yes';
} else {
return ABC(...rest);
}
};
console.log(ABC(8, 5, 6, 7));
如果你加几个 console.log
就更清楚了:
function ABC(num, ...rest) {
console.log(`num=`, num, ", rest=", rest)
if (num < 5) {
console.log(`returning 'yes'`)
return 'yes';
} else {
console.log(`returning [...ABC(${rest})]`)
return [...ABC(rest)];
}
};
console.log(ABC(8, 5, 6, 7));
- 运行 1: num=8 , rest=[5, 6, 7]
所以它进入 else
和 returns [...ABC([5, 6, 7])]
。只有一个参数,一个数组。所以在 运行 2:
- 运行 2 : num=[5, 6, 7] , rest= []
[5, 6, 7] < 5
?错误的。所以它再次进入 else
。它returns [...ABC([])]
.
- 运行 3 : num=[] , rest= []
[] < 5
?真的,很奇怪。所以 ABC([])
returns 'yes'
.
但是这个 'yes'
被返回 到前一个函数调用 ,即 [...ABC([])]
,它变成 [...'yes']
,它是 ['y', 'e', 's']
.