web-dev-qa-db-ja.com

大きな匿名関数を他の関数の引数としてJavaScriptで広く受け入れられているのはなぜですか?

意見(いくつかに共有されると確信しています)があり、数行以上のコードを含む匿名関数を引数として渡します他の関数は可読性と自己文書化に大きな影響を与えます。コードを使用して名前付き関数を宣言するだけの方がはるかに良いと私が思うまでです。または、main関数を宣言する前に、少なくともその無名関数を変数に割り当てます

ただし、多くのJavaScriptライブラリー(jQuery、d3.js/NVD3.js)は、いくつかの例を示すために、このように大きな関数を使用しています。

なぜこれがJavaScriptでそれほど広く受け入れられているのですか?それは文化的なものですか、それとも私が見逃していて、名前付き関数を宣言するよりも使用を優先する利点がありますか?

27
Adam Copley

私が考えることができる3つの主な理由:

  1. 親スコープアクセス
  2. プライバシー
  3. 上位スコープで定義された名前の削減

親スコープアクセス:インライン関数定義により、インラインコードは親スコープで定義された変数にアクセスできます。これは多くのことに非常に役立ち、適切に実行されればコードの量や複雑さを減らすことができます。

このスコープ外で定義された関数にコードを配置してからコードを呼び出す場合、関数にアクセスする必要がある親の状態を渡す必要があります。

プライバシー:インラインの匿名定義内のコードはよりプライベートであり、他のコードから呼び出すことはできません。

上位スコープで定義された名前の削減:これはグローバルスコープで操作する場合に最も重要ですが、インラインの匿名宣言により、現在のスコープで新しいシンボルを定義する必要がなくなります。 JavaScriptはネームスペースの使用をネイティブに必要としないため、最小限必要なものよりも多くのグローバルシンボルを定義しないことをお勧めします。


社説:何かを匿名でインラインで宣言することが、親スコープアクセスが使用されていない場合でも、関数を定義して呼び出すよりも「良い」と考えられているJavascriptの文化的なものになっているようです。これは、最初はJavascriptのグローバルな名前空間汚染の問題が原因であったと考えられますが、おそらくプライバシーの問題が原因でした。しかし、それは今やいくぶん文化的なものになり、あなたが言及するような多くの公共のコード体で表現されているのを見ることができます。

C++のような言語では、多くの場合、多くのページ/画面にまたがる1つの巨大な関数を持つことは、理想的とは言えない方法だと考えられます。もちろん、C++には組み込みのネームスペースがあり、親スコープへのアクセスを提供せず、プライバシー機能を備えているため、JavaScriptはコード式を使用してプライバシーと親スコープへのアクセスを実現する必要がありますが、読みやすさ/保守性によって完全に動機付けられます。したがって、JSは別の方向に動機付けされたように見えるだけであり、特定のケースではその方向付けを動機付けたものが必要ではない場合でも、それは言語の中でいくぶん文化的なものになっています。

23
jfriend00

匿名関数は、ほとんどの言語よりもJavaScriptで多くの目的に使用されます。

まず、名前空間とブロックスコープに使用されます。最近まで、JavaScriptにはモジュールまたは他の種類の名前空間メカニズムがありませんでした。そのため、匿名関数を使用して、モジュールパターンを介してその機能を提供しています。これらの関数に名前を付けてもまったくメリットはありません。 JavaScriptには ブロックスコープ が最近までなかったため、小規模ではありますが、ブロックスコープを模倣するために同様のパターンが使用されました。特にループの本体で。この場合、名前付き関数を使用すると、難読化が困難になります。

次に、JavaScript固有ではない匿名関数が、制御構造を模倣する高次関数と共に使用されることがよくあります。たとえば、jQueryのeachメソッドです。すべてのループ本体またはif分岐が数行を超える場合はいつでも、関数に抽象化することを疑っています。この場合も同じロジックが適用されます。

最後の理由は、JavaScriptでイベントベースのプログラミングが一般的であり、不注意な 継続渡しスタイル コードにつながる傾向があるためです。 AJAXを呼び出してコールバックを登録すると、実行時に別のAJAXを呼び出してコールバックを登録するなどになります。呼び出しが同期ではなく非同期の場合、これは単一の字句スコープ内の直線的なコードシーケンスにすぎません。繰り返しますが、直線的なコードの数行ごとに関数に抽象化することはできません。

文化的要因もあり、とりわけ上記の理由により、JavaScriptでは匿名関数が他の多くの言語よりもはるかに一般的であり、他の多くの言語より快適に/緩やかに使用されます。