Maison > interface Web > js tutoriel > Analyse et explication des fonctions récursives en JavaScript

Analyse et explication des fonctions récursives en JavaScript

黄舟
Libérer: 2017-11-18 10:28:58
original
2231 Les gens l'ont consulté

Nous vous avons déjà présenté la fonction récursive en php. En fait, les fonctions récursives sont généralement davantage utilisées dans le backend. Pour les développeurs back-end, la récursivité devrait être un jeu d’enfant, une chose très simple, mais de nombreux développeurs front-end n’en savent pas grand-chose. En fait, la récursivité est souvent utilisée dans le front-end. Aujourd'hui, nous allons analyser la fonction récursive en JavaScript pour vous !

js appelle récursivement

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

L'énorme flexibilité des fonctions en Javascript entraîne des difficultés pour utiliser le nom de la fonction lors de la récursion. Pour la déclaration de variable ci-dessus, f est. une variable, donc sa valeur peut être facilement remplacée :

var fn = f;  f = function () {};
Copier après la connexion

La fonction est une valeur, elle est affectée à fn, nous nous attendons à utiliser fn(5) pour calculer une valeur, mais en raison du fonction La variable f est toujours référencée, elle ne fonctionne donc pas correctement.

Donc, une fois que l'on définit une fonction récursive, il faut faire attention à ne pas changer facilement le nom de la variable.

Ce dont nous avons parlé ci-dessus, ce sont tous des appels fonctionnels. Il existe d'autres façons d'appeler des fonctions, comme les appeler en tant que méthodes objet.

Nous déclarons souvent des objets comme ceci :

var obj1 = {  
    num : 5,  
    fac : function (x) {  
        // function body  
    }  };
Copier après la connexion

Déclarons une fonction anonyme et affectons-la à l'attribut (fac) de l'objet.

Si nous voulons écrire une récursivité ici, nous devons référencer la propriété elle-même :

var obj1 = {  
    num : 5,  
    fac : function (x) {  
        if (x === 1) {  
            return 1;  
        } else {  
            return x * obj1.fac(x - 1);  
        }  
    }  };
Copier après la connexion

Bien sûr, elle souffrira également du même problème que l'appel de fonction :

var obj2 = {fac: obj1.fac};  
obj1 = {};  
obj2.fac(5); // Sadness
Copier après la connexion

Une fois la méthode affectée à l'attribut fac de obj2, obj1.fac doit encore être référencé en interne, donc... il échoue.

Une autre méthode sera améliorée :

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
Copier après la connexion

Récupérer les attributs dans le contexte lorsque la fonction est exécutée via le mot-clé this, afin que lorsque obj2.fac est exécuté, il soit référencé à l'intérieur de l'attribut de fonction fac d'obj2.

Mais la fonction peut aussi être appelée en modifiant arbitrairement le contexte, c'est-à-dire l'appel universel et l'application :

obj3 = {};  obj1.fac.call(obj3, 5); // dead again
Copier après la connexion

La fonction récursive ne peut donc plus fonctionner correctement.

Nous devrions essayer de résoudre ce problème. Vous souvenez-vous de la méthode de déclaration de fonction mentionnée précédemment ?

var a = function b(){};
Copier après la connexion

Cette méthode de déclaration est appelée une fonction en ligne. Bien que la variable b ne soit pas déclarée en dehors de la fonction, vous pouvez utiliser b() pour vous appeler à l'intérieur de la fonction, donc

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
Copier après la connexion

Ça y est, nous avons un nom que nous pouvons utiliser en interne sans nous soucier de savoir à qui la fonction récursive est attribuée et comment elle est appelée.

L'objet arguments à l'intérieur de la fonction Javascript a un attribut appelé, qui pointe vers la fonction elle-même. Il est donc également possible d'utiliser arguments.callee pour appeler des fonctions en interne :

function f(x) {  
    if (x === 1) {  
        return 1;  
    } else {  
        return x * arguments.callee(x - 1);  
    }  }
Copier après la connexion

Mais arguments.callee est une propriété qui est prête à être obsolète et est susceptible de disparaître dans une future version d'ECMAscript, dans ECMAscript 5 Lorsque "use strict", arguments.callee ne peut pas être utilisé.

La dernière suggestion est la suivante : si vous souhaitez déclarer une fonction récursive, veuillez utiliser new Function avec prudence. La fonction créée par Functionconstructor sera recompilée à chaque fois qu'elle est appelée. cela est appelé de manière récursive entraînera des problèmes de performances - vous constaterez que votre mémoire s'épuise rapidement.

Application de fonction récursive js

Lorsque je travaillais sur un projet récemment, j'ai utilisé une fonction récursive pour appeler les nœuds enfants de json et ajouter tous les nœuds enfants de json aux objets qui contiennent un certain nombre. , sont poussés dans un tableau, puis liés à celui-ci.

J'ai effectué l'appel récursif suivant

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数据")
Copier après la connexion

pour pousser toutes les données contenant un certain nombre en json vers le new_array array.

Résumé :

Je crois que grâce à l'explication ci-dessus, tout le monde aura une compréhension plus avancée des fonctions récursives non seulement. être utilisé en php, il peut également être utilisé en JavaScript front-end, j'espère que cela vous sera utile !

Recommandations associées :

Compréhension approfondie des fonctions récursives en JavaScript et partage d'exemples de code

Fonctions récursives en JS

Introduction à l'utilisation des fonctions récursives en JS

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal