gpt4 book ai didi

javascript - 递归函数有特殊的作用域规则吗?

转载 作者:行者123 更新时间:2023-12-03 06:41:35 26 4
gpt4 key购买 nike

我正在解决一个需要递归函数的问题,并且注意到嵌套执行似乎正在修改父级的参数:

var foo = function(ar) {
console.log('Calling function - Array: ' + ar.toString());
if(ar.length > 1){
var ele = ar.pop();
foo(ar);
console.log('Function recursion ends - Array: ' + ar.toString() + ' Popped: ' + ele);
return;
} else {
console.log('Function ends - Array: ' + ar.toString());
return;
}
}

foo([1,2,3]);

输出(压痕地雷):

/*
Calling function - Array: 1,2,3
Calling function - Array: 1,2
Calling function - Array: 1
Function ends - Array: 1
Function recursion ends - Array: 1 Popped: 2
Function recursion ends - Array: 1 Popped: 3 <-- What happened to 2?
*/

这看起来很奇怪 - 因为我用 [1,2,3] 调用了该函数我希望函数的第一次迭代仍然保留 ar 之间提供给它的所有元素和ele - 但当函数结束时,只有 1保留在提供的数组中 - 2 发生了什么?是否嵌套执行pop它超出了第一次执行的变量?

我对 JavaScript 中函数作用域的理解是,传递给函数的变量只能在本地修改它们,并且不能将它们导出回全局/父作用域,如下所示:

var bar = 'bar';

function doBar(bar){
bar = 'foo';
}

doBar(bar);
console.log(bar); //Outputs 'bar';

但是递归函数的输出似乎挑战了这种理解。

如何防止这些嵌套执行修改父级参数以恢复丢失的 2 ?我对 JavaScript 作用域的理解是错误的吗?

<小时/>

在打开这个问题之前,我可怜地试图捕获救命稻草,我尝试在闭包中执行该函数:

var foo = function(ar) {
console.log('Calling function - Array: ' + ar.toString());
if(ar.length > 1){
var ele = ar.pop();
(function(foo, ar){
foo(ar);
})(foo, ar)

console.log('Function recursion ends - Array: ' + ar.toString() + ' Popped: ' + ele);
return;
} else {
console.log('Function ends - Array: ' + ar.toString());
return;
}
}

但是我得到了与不使用闭包相同的结果 - 我怀疑是因为我明确传入 arfoo使其与没有关闭没有什么不同。

最佳答案

Array.prototype.pop()是一个可变操作。当您递归调用 foo 时,该可变操作在调用范围内仍然有效。范围内没有发生任何奇怪的事情,只是您可能期望 foo 中的操作无法修改您提供给它的参数的内部结构。数组通过引用传递,这意味着参数将引用调用范围所引用的同一个数组。

您可以调用 arr.slice(0, -1) 。这将返回数组的浅拷贝,而不是修改现有数组。它将改变您获取数组最后一个索引的方式。

var foo = function(ar) {
console.log('Calling function - Array: ' + ar.toString());
if(ar.length > 1){
var ar2 = ar.slice(0, -1);
foo(ar2);
console.log('Function recursion ends - Array: ' + ar2.toString() + ' Popped: ' + ar.slice(-1));
return;
} else {
console.log('Function ends - Array: ' + ar.toString());
return;
}
}

foo([1,2,3]);

关于javascript - 递归函数有特殊的作用域规则吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37934329/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com