>웹 프론트엔드 >JS 튜토리얼 >JavaScript의 재귀함수 분석 및 설명

JavaScript의 재귀함수 분석 및 설명

黄舟
黄舟원래의
2017-11-18 10:28:582233검색

이전에 PHP에서 재귀 함수를 소개한 적이 있습니다. 실제로 재귀 함수는 일반적으로 백엔드에서 더 많이 사용됩니다. 백엔드 개발자에게 재귀는 매우 간단한 일이지만 많은 프런트엔드 개발자는 이에 대해 잘 모릅니다. 실제로 재귀는 프론트엔드에서 자주 사용되는데요, 오늘은 JavaScript에서 재귀함수를 분석해보겠습니다!

js 재귀 호출

// 一个简单的阶乘函数  var f = function (x) {  
    if (x === 1) {  
        return 1;  
    } else {  
        return x * f(x - 1);  
    }  };

Javascript의 함수의 유연성이 커서 재귀 시 함수 이름을 사용하기가 어렵습니다. 위의 변수 선언에서 f는 변수이므로 해당 값을 쉽게 대체할 수 있습니다.

var fn = f;  f = function () {};
함수는 다음과 같습니다. fn에 할당된 값 fn(5)을 사용하여 값을 계산할 것으로 예상하지만 변수 f가 여전히 함수 내에서 참조되기 때문에 제대로 작동할 수 없습니다.

그러므로 재귀함수를 정의한 후에는 변수의 이름이 쉽게 변경되지 않도록 주의해야 합니다.

위에서 이야기한 것은 모두 함수 호출입니다. 함수를 객체 메서드로 호출하는 등 다른 방법으로 호출할 수 있습니다.

우리는 종종 다음과 같이 객체를 선언합니다:

var obj1 = {  
    num : 5,  
    fac : function (x) {  
        // function body  
    }  };

익명 함수

를 선언하고 이를 객체의 속성(fac)에 할당합니다. 여기서 재귀를 작성하려면 속성 자체를 참조해야 합니다.

var obj1 = {  
    num : 5,  
    fac : function (x) {  
        if (x === 1) {  
            return 1;  
        } else {  
            return x * obj1.fac(x - 1);  
        }  
    }  };

물론 함수 호출 메서드와 동일한 문제도 발생합니다.

var obj2 = {fac: obj1.fac};  
obj1 = {};  
obj2.fac(5); // Sadness

메서드가 fac 속성에 할당된 후 obj2의 내부 obj1.fac를 참조하려면... 실패했습니다.

또 다른 방법이 개선될 예정입니다:

var obj1 = {  
     num : 5,  
     fac : function (x) {  
        if (x === 1) {  
            return 1;  
        } else {  
            return x * this.fac(x - 1);  
        }  
    }  };  var obj2 = {fac: obj1.fac};  obj1 = {};  obj2.fac(5); // ok

this 키워드를 통해 함수가 실행될 때 컨텍스트의 속성을 가져오면 obj2.fac가 실행될 때 obj2의 fac 속성이 함수 내에서 참조됩니다.

하지만 컨텍스트를 임의로 수정하여 함수를 호출할 수도 있습니다. 즉, 범용 호출 및 적용:

obj3 = {};  obj1.fac.call(obj3, 5); // dead again

그래서 재귀 함수가 다시 제대로 작동하지 않습니다.

이 문제를 해결하도록 노력해야 합니다. 앞서 언급한 함수 선언 방법을 기억하시나요?

var a = function b(){};

이 선언 방법을 인라인 함수라고 합니다. b 변수는 함수 외부에서 선언되지 않지만 b()를 사용하여 함수 내부에서 자신을 호출할 수 있으므로

var fn = function f(x) {  
    // try if you write "var f = 0;" here  
    if (x === 1) {  
        return 1;  
    } else {  
        return x * f(x - 1);  
    }  };  
    var fn2 = fn;  fn = null;  fn2(5); // OK  // here show the difference between "var f = function f() {}" and "function f() {}"  var f = function f(x) {  
    if (x === 1) {  
        return 1;  
    } else {  
        return x * f(x - 1);  
    }  };  var fn2 = f;  f = null;  fn2(5); // OK  var obj1 = {  
    num : 5,  
    fac : function f(x) {  
        if (x === 1) {  
            return 1;  
        } else {  
            return x * f(x - 1);  
        }  
    }  };  var obj2 = {fac: obj1.fac};  obj1 = {};  obj2.fac(5); // ok  var obj3 = {};  obj1.fac.call(obj3, 5); // ok

그렇습니다. 재귀 함수가 누구에게 할당되고 어떻게 호출되는지 걱정할 필요 없이 내부적으로 사용할 수 있습니다.

Javascript 함수 내부의 인수 개체에는 함수 자체를 가리키는 호출 수신자 속성이 있습니다. 따라서 인수.callee를 사용하여 내부적으로 함수를 호출할 수도 있습니다.

function f(x) {  
    if (x === 1) {  
        return 1;  
    } else {  
        return x * arguments.callee(x - 1);  
    }  }

그러나 인수.callee는 더 이상 사용되지 않을 속성이며 ECMAscript 5에서 "use strict"가 사용되는 경우 향후 ECMAscript 버전에서 사라질 가능성이 높습니다. , Arguments.callee를 사용할 수 없습니다.

마지막 제안은: 재귀 함수를 선언하려면 새로운 Function 메서드를 주의해서 사용하세요. Function

Constructor

에 의해 생성된 함수는 호출될 때마다 함수로 다시 컴파일됩니다. 문제 - 메모리가 매우 빨리 소모된다는 것을 알게 될 것입니다. js 재귀 함수 적용

최근 프로젝트를 진행하면서 재귀 함수를 사용하여 json의 하위 노드를 호출하고 json의 하위 노드에 있는 특정 숫자를 포함하는 모든 개체를 배열로 푸시한 다음 바인딩했습니다. 그것.

다음 재귀 호출

var new_array=[];
     function _getChilds(data){
         if(data.ObjType=="某个数"){
            new_array.push(cs_data);
        }
        if(data.Childs){
          if(data.Childs.length>0){
              getChilds(data.Childs)
          }
       }
     }
    function getChilds(data){
        for(var i=0;i<data.length;i++){
            _getChilds(data[i]);
        }
    }使用方法:getChilds("json数据")

을 통해 json에 특정 숫자가 포함된 모든 데이터를 new_

배열 배열

으로 푸시했습니다.

요약: 위의 설명을 통해 모든 사람이 재귀 함수에 대해 더 발전된 이해를 갖게 될 것이라고 믿습니다. php뿐만 아니라 프론트엔드 JavaScript에서도 사용할 수 있습니다. 도움이 되었기를 바랍니다.

관련 권장 사항:

JavaScript의 재귀 함수에 대한 심층적인 이해 및 샘플 코드 공유

JS의 재귀 함수 사용 소개

위 내용은 JavaScript의 재귀함수 분석 및 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.