CommonJSモジュールは、次のイディオムを使用して定義されているのが一般的です。
(function() {
var logThis = function() { console.log(this); }
module.exports = logThis;
}).call(this);
私はちょうど30分を同僚と話し合って、なぜ彼らがでクロージャーを呼び出すのかを話し合っていcall(this)
ます。これによりthis
、クロージャ内の値は、グローバルオブジェクトに設定されるのではなく、呼び出し元から継承されます。ただし、これをNode.jsでテストした場合this
、モジュール内の値は、次のようにロードして実行した場合でも、常にグローバルオブジェクトでした。
var bar = {};
bar.foo = function() { var foo = require("./foo"); foo(); }
コンソールにオブジェクトが表示されることを本当に期待していましたbar
が、実際にはグローバルオブジェクトが表示されます。その後、Underscore.jsなどのモジュールがWebコンテキストでも使用されていることが原因である可能性があることに気付きました。ただし、その場合は<script>タグがロードされるためthis
、とにかく常にグローバルオブジェクトと等しくなります。
何が得られますか?この構成を使用する理由は確かにありますが、モジュールがNode.jsで使用されているか、Webページで使用されているかにかかわらず、この特定のケースで実際的な違いはわかりません。
更新:明確にするために、これが違いを生む可能性のあるいくつかのケースを考えることができます。たとえば、私が言う場合:
var bar = {}
var foo = require("./foo");
bar.foo = foo;
bar.foo();
(元の例を修正してくれた@Pointyに感謝します。)
モジュール内のクロージャは、が呼び出されたときに評価されることを期待します。つまり、モジュール内require()
の値はグローバルオブジェクトにバインドされ、「バー」のメンバーとして呼び出されてthis
もコンソールに書き込まれます。 foo()
" 物体。ただし、この例でも、コンソールに「bar」オブジェクトが表示されています。私はそれthis
が私が期待したように閉鎖に縛られていないと思いますか?
一言で言えば、Underscore.jsのようなモジュールが、Node.jsまたはWebページのいずれかで、fn.call(this)
だけでなくで呼び出されたクロージャーにラップされているために、異なる動作をする1つの例を探しています。fn()