Javascript 闭包、递归和settimeout-记录空数组

Javascript 闭包、递归和settimeout-记录空数组,javascript,arrays,recursion,closures,settimeout,Javascript,Arrays,Recursion,Closures,Settimeout,正在递归调用以下函数,并为“input”和常量“delay”传递不同的值。为“input”传递的值是一个对象数组。我所经历的奇怪行为是,虽然第一个console.log单独记录每个数组,但settimeout中的一个会记录多个空数组,并且只有最后一个数组中有实际值: function setDelay(input, delay) { console.log(JSON.parse(JSON.stringify(input))); setTimeout(function() { co

正在递归调用以下函数,并为“input”和常量“delay”传递不同的值。为“input”传递的值是一个对象数组。我所经历的奇怪行为是,虽然第一个console.log单独记录每个数组,但settimeout中的一个会记录多个空数组,并且只有最后一个数组中有实际值:

function setDelay(input, delay) {
  console.log(JSON.parse(JSON.stringify(input)));
  setTimeout(function() {
    console.log(JSON.parse(JSON.stringify(input)))
  }, delay)
}
根据我对闭包工作原理的理解,我猜两者应该总是相同的,因为值是单独传递给每个函数的,然后以后在展开过程中可用,与第一次调用时可用的方式相同

我还尝试了使用try-catch的代码变体,但得到了相同的结果。有人知道我对结束的理解缺乏细节吗


编辑:在这里您可以找到整个递归实现:

您正在记录相同的数组,但其项发生了变化。如果希望项目始终相同,则需要复制数组。因为您使用的是
JSON.stringify
,所以很简单:

function setDelay(input, delay) {
  input = JSON.parse(JSON.stringify(input));
  console.log(input);
  setTimeout(function() {
    console.log(input)
  }, delay)
}

使用
shift
unshift
splice
,可以变异数组。因此,尽管您在两个位置克隆了相同的项目,但当它处于不同的状态时,您会这样做。您可以通过返回新项目而不在
mergeSort
中进行变异来解决此问题。请注意,要求海报在此处包含其代码的原因是,有时不清楚什么是相关的。在这种情况下,重要的代码没有显示在站点上,而是被卡在一个外部资源(JSBin)中,可能会被修改或删除。所以下一次,确保你包括了任何可能涉及实际问题的内容,而不仅仅是一个链接。