为什么这个函数 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'].