2011-09-02 4 views
0

나는 브라우저 푸딩 코드에 의해 모든 시간을 못을 박았다지고 중지의 추측하지만,이 :자바 스크립트에서 재귀가 얼마나 제한적입니까?

 function print(item) { 
      document.getElementById('output').innerHTML = 
       document.getElementById('output').innerHTML 
       + item + '<br />'; 
     } 

     function recur(myInt) { 
      print(myInt); 
      if (int < 10) { 
       for (i = 0; i <= 1; i++) { 
        recur(myInt+1); 
       } 
      } 
     } 

는 생산 :

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
10 

아니라 내가 얻을 오래된 큰 혼란을 내가 할 때

 function recur(myInt) { 
      print(myInt); 
      if (int < 10) { 
       for (i = 0; i <= 1; i++) { 
        var x = myInt + 1; 
        setTimeout("recur("+x+")"); 
       } 
      } 
     } 

뭔가가 누락되었거나 JS에서 재귀를 수행하는 방법입니까? 각 자식에 대해 메서드를 호출해야하는 재귀를 사용하여 트리를 탐색하는 데 관심이 있습니다.

+1

'if (int <10)'는 if 블록을 실패하고 재귀를 중지합니다. 그것이 모든 언어에서 예상되는 행동입니다. – jiggy

+1

변수 이름을 "int"로 지정하지 마십시오. js에서는 합법적 일 수 있지만 다른 많은 언어에서는 예약어이기 때문에 혼란 스럽습니다. –

+0

두 가지 버전의 메서드는 동일한 코드를 반환해야합니다. 두 번째 버전에서는 메서드 자체가 두 번 호출 될 것으로 예상하므로 많은 양의 숫자를 생성하지 않습니다. – gordatron

답변

4

전역 변수를 루프 카운터로 사용하기 때문에 가장 안쪽으로 호출 할 때만 루프가 실행됩니다. 통화에서 돌아 오면 카운터는 이미 다른 루프의 루프 끝을 벗어났습니다.

function recur(int) { 
    print(int); 
    if (int < 10) { 
     for (var i = 0; i <= 1; i++) { 
      recur(int + 1); 
     } 
    } 
} 

출력은 타임 아웃을 사용하는 경우와 동일한 수의 항목은 다음과 같습니다 로컬 변수를 한 경우

. 타임 아웃을 사용하면 전역 변수는 동일한 문제를 일으키지 않습니다. 순환에서 벗어 났을 때 재귀 호출이 대기열에 올려 져 나중에 실행되기 때문입니다.

+0

우수한! 감사! 나는 내가 뭔가를 놓친다는 것을 알았다 ... 나는 그곳에 var를 가지고 있었다. 그러나 웬일인지 나는 그것을 제거했다! – gordatron

+0

어리석은 생각으로 바깥에서 이것을 가져다 놓으면 세계적인 범위에 놓이게 될 것 같아요. 아 .. 아직도 JS를 배우고 있어요 ;-) – gordatron

1

재귀는 JavaScript에서 매우 제한적입니다. 당신의 나무가 아주 깊지 않다면 괜찮을 것입니다. 수백만 개의 요소가있는 대부분의 트리는 상당히 넓기 때문에 스택에서 대부분의 log (n) 재귀 호출을 얻습니다. 이는 일반적으로 문제가되지 않습니다. setTimeout은 확실히 필요하지 않습니다. 첫 번째 예제에서와 마찬가지로, 가끔씩 재귀가 끝나도록 가드 절이 필요할 때가 있습니다.

+0

이것은 자신의 어려움의 근원 인 범위 문제를 다루지 않습니다 – antlersoft

2

나는 당신의 잘못을 알고 있습니다. 함수의 재귀는 특정 범위를 유지하므로 루프가 한 번 실행될 때마다 반복자 (i)가 실제로 각 범위에서 증가합니다. 이 둘은 서로를 작성하는 동안-에서 반복자를 중지 지금 'var에 나는 = 0'

function recur(int) { 
      print(int); 
      if (int < 10) { 
       for (var i = 0; i <= 1; i++) { 
        recur(int+1); 
       } 
      } 
     } 

참고. 타임 아웃을 설정하면 나머지 루프를 실행하기 전에 첫 번째 루프가 실행을 마칠 수 있었고, 또한 마지막 반복기의 종료를 제거 할 수있는 윈도우 객체를 실행하게됩니다.

관련 문제