ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptの再帰関数の解析と解説
以前、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
このキーワードを通じて関数が実行されるときにコンテキスト内の属性を取得します。これにより、obj2.fac が実行されるときに、obj2 の fac 属性が関数内で参照されます。
しかし、この関数はコンテキストを任意に変更することによって呼び出すこともできます。これはユニバーサル呼び出しと適用です:
obj3 = {}; obj1.fac.call(obj3, 5); // dead again
そのため、再帰関数は再び適切に動作できなくなります。
この問題を解決してみるべきです。前に述べた関数の宣言方法を覚えていますか?
var a = function b(){};
この宣言方法はインライン関数と呼ばれます。変数 b は関数の外で宣言されませんが、関数内で b() を使用して自分自身を呼び出すことができます。再帰関数が誰に割り当てられ、どのように呼び出されるかを気にすることなく内部的に使用できます。
JavaScript 関数内の引数オブジェクトには、関数自体を指す callee 属性があります。したがって、arguments.callee を使用して内部的に関数を呼び出すこともできます:
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
ただし、arguments.callee は非推奨になる予定の属性であり、ECMAscript 5 で「use strict」が使用されている場合、将来の ECMAscript バージョンでは消える可能性があります。 , Arguments.callee は使用できません。
最後の提案: 再帰関数を宣言したい場合は、Function
Constructorによって作成された関数は、再帰呼び出しによってパフォーマンスが低下する可能性があるので、注意して使用してください。問題 - メモリがすぐに使い果たされることがわかります。
js再帰関数の応用最近あるプロジェクトに取り組んでいたとき、再帰関数を使ってjsonの子ノードを呼び出し、jsonの子ノードにある特定の番号を含むオブジェクトをすべて配列にpushしてバインドしました。それ。
次の再帰呼び出し
function f(x) { if (x === 1) { return 1; } else { return x * arguments.callee(x - 1); } }
を介して、json内の特定の数値を含むすべてのデータをnew_
array配列にプッシュしました。
上記の説明を通じて、再帰関数は PHP で使用できるだけでなく、フロントエンド JavaScript でも使用できることを誰もがより深く理解できると思います。お役に立てば幸いです。
関連する推奨事項:
JavaScript の再帰関数の詳細な理解とサンプル コードの共有
以上がJavaScriptの再帰関数の解析と解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。