Я работаю над проблемой, которая требует рекурсивной функции и заметил, что вложенные казни, как представляется, изменение параметров материнской компании:Имеют ли рекурсивные функции специальные правила определения области видимости?
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;
}
}
Но я получил те же результаты, без использования закрытия - Я подозреваю, потому что я явно проходил в ar
и foo
, делая его ничем иным, как без закрытия.
Уплотненный Foo() выполняется на массиве, прежде чем войти что-нибудь. Попробуйте выполнить регистрацию до вложенного 'foo()' – charlietfl
Нет, нет ничего особенного в рекурсии, и это не имеет ничего общего с областью видимости. Каждый вызов создает свою собственную переменную 'ar'. Просто они ссылаются на один и тот же объект массива, а 'pop' мутирует его. – Bergi
К тому времени, когда вы начинаете регистрировать «Рекурсия функции заканчивается ...», что «есть», что вам подсказывает консоль? – JonSG