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); } };
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 () {};
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 } };
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); } } };
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
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
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
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(){};
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
Ç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); } }
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数据")
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
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!