web-dev-qa-db-ja.com

なぜ匿名関数を定義し、jQueryを引数として渡すのですか?

私は、backbone.jsスクリーンキャストからの優れたpeepcodeデモコードを見ています。その中で、バックボーンコードはすべてjQueryオブジェクトに渡される匿名関数に囲まれています。

(function($) {
  // Backbone code in here
})(jQuery);

私自身のバックボーンコードでは、jQuery DOMの「準備完了」イベントですべてのコードをラップしました。

$(function(){
  // Backbone code in here
});

最初のアプローチのポイント/利点は何ですか?この方法で匿名関数を作成すると、関数引数として渡されるjQueryオブジェクトを使用してすぐに実行され、$がjQueryオブジェクトであることが効果的に保証されます。これが唯一のポイントですか?jQueryが '$'にバインドされていることを保証するか、これを行う他の理由がありますか?

92
Matt Roberts

示した2つのコードブロックは、実行するタイミングと理由が劇的に異なります。それらは互いに排他的ではありません。それらは同じ目的に役立ちません。

JavaScriptモジュール


(function($) {
  // Backbone code in here
})(jQuery);

これは、「JavaScriptモジュール」パターンであり、即時呼び出し関数で実装されます。

このコードの目的は、コードに「モジュール性」、プライバシー、およびカプセル化を提供することです。

これの実装は、(jQuery)括弧を呼び出すことですぐに呼び出される関数です。 jQueryを括弧に渡す目的は、グローバル変数にローカルスコープを提供することです。これは、$変数を検索するオーバーヘッドの量を減らすのに役立ち、場合によっては、ミニファイヤの圧縮/最適化を改善できます。

すぐに呼び出し関数が実行されます。関数の定義が完了するとすぐに、関数が実行されます。

jQueryの「DOMReady」関数

これは、jQueryの「DOMReady」関数のエイリアスです。 http://api.jquery.com/ready/


$(function(){
  // Backbone code in here
});

jQueryの「DOMReady」関数は、DOMがJavaScriptコードによって操作される準備ができたときに実行されます。

バックボーンコードのモジュールとDOMReady

JQueryのDOMReady関数内でBackboneコードを定義するのは悪い形式であり、アプリケーションのパフォーマンスを損なう可能性があります。この関数は、DOMが読み込まれ、操作の準備ができるまで呼び出されません。つまり、オブジェクトを定義する前に、ブラウザーが少なくとも1回DOMを解析するまで待っているということです。

DOMReady関数の外部でBackboneオブジェクトを定義することをお勧めします。私は、とりわけ、コードのカプセル化とプライバシーを提供できるように、JavaScriptモジュールパターン内でこれを行うことを好みます。私は「Revealing Module」パターン(上記の最初のリンクを参照)を使用して、モジュールの外部で必要なビットへのアクセスを提供する傾向があります。

DOMReady関数の外部でオブジェクトを定義し、それらを参照する何らかの方法を提供することにより、ブラウザーがJavaScriptの処理を有利に開始できるようになり、ユーザーエクスペリエンスが向上する可能性があります。また、物事を移動するときにDOMREady関数を作成することを心配せずに物事を移動できるため、コードがより柔軟になります。

Backboneオブジェクトを別の場所で定義したとしても、おそらくDOMReady関数を使用するでしょう。その理由は、多くのBackboneアプリが何らかの方法でDOMを操作する必要があるためです。これを行うには、DOMの準備ができるまで待つ必要があります。そのため、DOMReady関数を使用して、定義後にアプリケーションを起動する必要があります。

これについてはWeb上で多くの例を見つけることができますが、モジュールとDOMReady関数の両方を使用した非常に基本的な実装を次に示します。



// Define "MyApp" as a revealing module

MyApp = (function(Backbone, $){

  var View = Backbone.View.extend({
    // do stuff here  
  });

  return {
    init: function(){
      var view = new View();
      $("#some-div").html(view.render().el);
    }
  };

})(Backbone, jQuery);



// Run "MyApp" in DOMReady

$(function(){
  MyApp.init();
});
172
Derick Bailey

副次的な注意事項として、匿名関数への引数として$を送信すると、$関数が頻繁に呼び出される場合、パフォーマンスにわずかにプラスの意味を持つ$ localがその関数に対してローカルになります。これは、javascriptが最初に変数のローカルスコープを検索してから、ウィンドウスコープ(通常は$が存在する)まで下に移動するためです。

14
joidegn

$.noConflict() が使用されていても、そのクロージャ内で$を常にalways使用できることが保証されます。

このクロージャーがなければ、常に$の代わりにjQueryを使用することになります。

9
ThiefMaster

これは、$変数の潜在的な競合を回避するためです。他の何かが$という変数を定義している場合、プラグインは間違った定義を使用する可能性があります

詳細については http://docs.jquery.com/Plugins/Authoring#Getting_Started を参照してください

4
Andrew Brock

両方を使う。

ライブラリーの競合を防ぎ、jQueryが$で期待されるとおりに使用可能であることを確認するためにjQueryを渡す自己呼び出し関数。

そして、DOMがロードされた後にのみJavaScriptを実行するために必要な.ready()ショートカットメソッド:

(function($) {
    $(function(){
          //add code here that needs to wait for page to be loaded
    });

    //and rest of code here
})(jQuery);
1
Andrew