はじめに
多くの従来の言語 (C/C/Java/C# など) では、関数は言語キーワードを使用して宣言し、必要に応じて呼び出すことしかできません。関数をパラメータとして使用する 別の関数に渡す、ローカル変数に代入する、または戻り値として使用するには、関数ポインタやデリゲートなどの特別なメソッドを経由する必要があります。
JavaScript の世界では、関数は従来の関数の使用方法 (宣言と呼び出し) をすべて備えているだけでなく、値を割り当てたり、パラメーターを渡したり、単純な値を返したりすることもできます。このような関数は 3 番目の関数とも呼ばれます。 -クラスの関数。それだけでなく、JavaScript の関数はクラスのコンストラクターとしても機能し、Function クラスのインスタンスです。このような複数のアイデンティティにより、JavaScript 関数は非常に重要になります。
1. 初心者レベルの JavaScript 関数
他の言語と同様、JavaScript 関数は最初に宣言して後で使用するという原則に従い、関数名には文字、数字、アンダースコア、または $ のみを含めることができ、数字で始めることはできません。関数を宣言するには 2 つの一般的な方法があります:
関数宣言の上記 2 つの方法には微妙な違いがあることに注意してください。最初のメソッドは、呼び出し前、呼び出し後、または実行されない位置で宣言されたかどうかに関係なく、宣言された時点では名前付き関数です。 (return ステートメントや決して true にならない分岐内など) はスコープ全体でアクセスできます。2 番目の方法は、厳密には関数宣言ではない匿名関数を変数に割り当てる方法です (関数宣言)。この関数は、代入の前にコードからアクセスすることはできません。つまり、呼び出す前に代入を完了する必要があります。そうしないと、呼び出し時にエラー「TypeError: unknown is not a function」が発生します。例:
2. 高度な JavaScript 関数
2.1 匿名関数と入れ子関数
JavaScript では、匿名関数と呼ばれる、名前のない関数を宣言できます。同時に、JavaScript では、入れ子関数と呼ばれる関数を関数内で宣言することもできます。入れ子関数のスコープは親関数全体です。
前の関数宣言のセクションでは、匿名関数と入れ子関数の使用について説明しました。匿名関数には名前がないため、コンテキストを汚染する新しい変数が導入されることはなく、新しい変数スコープがもたらされます。地球環境汚染を防ぐために使用されます。
JavaScript ランタイムには特別なグローバル環境 (グローバル オブジェクト) があり、このオブジェクトにはグローバル関数と変数が格納されます。実際の開発では、グローバル オブジェクト変数に重複が発生した場合に、複数のサードパーティ ライブラリや複数の JS ファイルが使用されることがよくあります。または関数宣言はコード実行時に混乱を引き起こします。たとえば、2 つの js ファイルが続けて導入され、それぞれが内部使用のために独自の関数ログを定義します。2 番目に導入された関数は最初の定義を上書きし、後続の実行でログ関数を呼び出しても問題が発生しない可能性があります。エラーの原因となります。現時点では、匿名関数を使用して js 全体にロジックをラップすると、このエラーを回避できます。この方法は、ほとんどのオープン ソース js ライブラリで使用されています。
関数がパラメータまたは戻り値として使用される場合、それは高階関数と呼ばれます。これは、JavaScript のすべての関数が高階関数として使用できることです。これも、1 番目のタイプの関数の特徴です。以下では、これら 2 つの使用方法をそれぞれ分析します。
上記のコードは、関数をパラメーターとして別の関数プロセス呼び出しに渡す例を示しています。プロセス関数の実装では、コールバックはブラック ボックスとして扱われ、パラメーターを渡して取得する役割を果たします。戻り値の具体的な実装は以前は明確ではありませんでした。 20 行目と 22 行目が実行される場合のみ、コールバックはそれぞれ負または二乗で表され、各要素に対して逆の値または二乗値の演算がそれぞれ実行されます。
2.3 終了
クロージャ (クロージャ) は新しい概念ではありません。クロージャは多くの関数型言語で使用されます。 JavaScript では、インライン関数内の外部関数のスコープ内で変数を使用するときにクロージャが使用されます。一般的な例えを使用して、クロージャとクラスの関係を説明します。クラスは関数を伴うデータであり、クロージャはデータを伴う関数です。
クロージャで使用される変数の特徴の 1 つは、親関数が返されたときに変数が解放されず、クロージャのライフ サイクルが終了したときに終了することです。たとえば、前のセクションのジェネレーターの例のように、gen1 と gen2 は、gen1 または gen2 の 2 つの変数が同じである限り、独立変数 i を使用します (gen1 の i が 1 増加しても、gen2 の i は影響を受けず、その逆も同様です)。 JavaScript エンジンによってガベージ コレクションされない場合、それぞれの変数 i は解放されません。 JavaScript プログラミングでは、クロージャは無意識のうちに使用されますが、クロージャのこの機能により使いやすさがもたらされますが、メモリ リークなどの問題が発生しやすくなります。例:
2.4 クラス コンストラクター
JavaScript 関数はクラスのコンストラクターとしても機能するため、関数を宣言している限り、new キーワードを使用してクラスのインスタンスを作成できます。
コードをコピー
3.1 関数クラス
JavaScript ランタイムには Function と呼ばれる組み込みクラスがあり、 function キーワードを使用して関数を宣言することは、実際には Function クラス オブジェクトを作成する短縮形式です。すべての関数には、call、apply、などの Function クラスのメソッドがすべて含まれています。そして、bind を実行します。このステートメントは、instanceof キーワードを使用して検証できます。
Function はクラスであるため、そのコンストラクターは Function であり (それ自体も Function クラスのオブジェクトです)、new キーワードを通じて関数オブジェクトを生成できるはずです。ここで最初のモンスターが登場します。それは、Function クラスを使用して関数を構築する方法です。 Function の構文は次のとおりです:
多くの言語では、一度関数を宣言すると、同じ名前の関数を再度宣言することはできず、構文エラーが発生します。ただし、JavaScript の関数は繰り返し宣言できるだけでなく、関数自体を更新することもできます。自らを喰らう怪物がここに!
コードをコピー
JavaScript 関数は非常に強力で、多くの問題を見事に解決しますが、多くのマイナスな問題も引き起こします。モンスターレベルの関数の使い方は、あまり知られていないものです。特に必要な場合を除き、安易に使用しないでください。そうしないと、コードが読みにくくなり、開発効率に影響します。
* 新しい ECMAScript では Strict モードが導入され、eval 関数が大幅に制限され、環境が汚染されないようにすることもできます
理解できましたか? 非常に実践的な内容です。不足している点があれば、専門家に指導を求めてください。一緒に進歩していきましょう。