5

RequireJS と Node.js (および一般的な JavaScript) についての理解が限られているため、よく知られている JavaScript ライブラリのソースを参照することがよくあります。このようなものを見るたびに:

( // Wrapping
    function (root, factory) {
        if (typeof exports === 'object') { // Node.js

            var underscore = require('underscore');
            var backbone = require('backbone');

            module.exports = factory(underscore, backbone);

        } else if (typeof define === 'function' && define.amd) { // Require.JS

            define(['underscore', 'backbone'], factory);

        } 
    }(this, function (_, Backbone) { // Factory function, the implementation
        "option strict";

        function Foo() {}

        return Foo; // Export the constructor
    })
); // Wrapping

私が理解できること(うまくいけば):

  • スクリプトが<script>タグに含まれていない場合、コードをラップする無名関数が自動的に実行されます
  • このコードは、RequireJS と Node.js の両方で機能します (if最初のチェック)。関数の結果は(Node.js)factoryに割り当てられるか、関数の引数として使用されます (RequireJS)。module.exportsdefine

Q1 : このコードは RequireJS と Node.js なしでどのように機能しますか? チェックは失敗し、if関数は実行されず、スクリプトは何も返しません。else iffactory

Q2 :引数thisとして渡す目的は何ですか? root一度も使用されていません

4

2 に答える 2

5

実際、あなたの質問で切り取られたコードは、ブラウザのグローバルでは機能しないと思います。この切り取りで使用されるパターンは、UMD-ユニバーサルモジュール定義と呼ばれます。実際、このパターンには多くのバリエーションがあります。https://github.com/umdjs/umdで他の例を参照できます。

質問について:

Q1 このスニペットは、NodeJSとdefine関数の明らかな理由(2つのチェックのみ)のため、RequireJSまたはその他のAMDローダーがないブラウザーでは機能しません。そのため、AMDライブラリを使用しないとファクトリー関数は呼び出されません。

ファクトリ関数を呼び出すには、ブラウザグローバルに別の条件を追加するだけです。

if (typeof exports === 'object') { // Node.js
    var underscore = require('underscore');
    var backbone = require('backbone');
    module.exports = factory(underscore, backbone);

} else if (typeof define === 'function' && define.amd) { // Require.JS
     define(['underscore', 'backbone'], factory);
} else {
    // Browser globals
    factory(root._, root.Backbone);
}

ラッパー関数に渡されたルートオブジェクトを使用し、nekmanが指摘したようにwindow、ブラウザ環境で設定されることに注意してください。そのため、そのウィンドウで定義されたグローバルオブジェクトをファクトリに渡すだけです。これらのオブジェクトは通常script、ページ上の他のタグによって定義されます。これがあなたの2番目の質問に答えることを願っています。

于 2013-02-08T22:23:58.567 に答える
2

Q1:と の両方が失敗ifした場合、 と がタグからロードされているとelse if想定するだけです。しばらく前に、同じ仮定を行うBackbone.localStorage プラグインにコミットを追加しましたunderscoreBackbone<script>

Q2:this「グローバル オブジェクト」を指します (windowブラウザー環境とglobalNode.js 環境で)。あなたの場合、それは使用されておらず、渡す必要はありません。factory単独で十分です。

于 2013-02-08T21:15:16.020 に答える