3

module.exports の使い方をひどく誤解していると思います。すべてのモジュールが、最後のモジュールが吐き出したものを上書きしているようです。

app.js :

var express = require("express")
    , app = express()
    , routes = require('routes')
    , server = app.listen(1337, "0.0.0.0")
    , io = require('socket.io').listen(server)
    , redis = require("redis")
    , client = redis.createClient();

var moduleA = require("./moduleA")(io, client);(socket.io と redis クライアントを渡す必要があります)

var moduleB = require("./moduleB")(io, client);(同じ)

moduleA.js :

module.exports = function(io, client){ 
    this.test = 'foo';
    return this;
};

moduleB.js :

module.exports = function(io, client){ 
    this.test = 'bar';
    return this;
};

app.jsに戻ります:

console.log(moduleB.test);( "バー" を表示)

console.log(moduleA.test);( "bar"表示されます)

誰かが私が間違っていることを説明できますか? exportsヘルパー (?) 自体がパラメーターを受け入れないように見えるため、これを行う他の方法は考えられません。

4

1 に答える 1

8

コンストラクターをエクスポートしています。呼び出すのではなく、構築する必要があります。

変化する

var moduleA = require("./moduleA")(io, client);

var moduleA = new (require("./moduleA"))(io, client);

または(明確にするために)

var ModuleA = require("./moduleA");
var a = new ModuleA(io, client);

あなたが見ているのは、ずさんなモードでコンストラクターを関数として呼び出すときの通常の動作です:thisグローバルオブジェクトを参照します。したがって、もちろん、2 つの場所からグローバル オブジェクトを変更すると、互いに上書きされ、戻るthisとグローバル オブジェクトが返されます。これは自分でテストできます: 現在のコードで、

moduleA === moduleB === this === global

このように再び自分の足を撃たないようにする 1 つの方法は、ずさんなモードの代わりに厳密なモードを使用することです。これを行うには、次の行を追加します

"use strict";

あなたが書くすべてのモジュールの一番上に(他のコードの前に)。厳密モードでは、 isthisなしで呼び出されたコンストラクターの場合、より早く、より理解しやすいエラーが発生します。newundefined

Strict モードには、この種の多くの利点があります。概要については、 [1][2][3]を参照してください。


別の解決策は、コンストラクターの使用を完全に停止し、代わりにファクトリー関数を使用することです。これは次のようになります。

module.exports = function (io, client) {
    var result = {};
    result.test = "foo";
    return result;
};

return thisコンストラクターでそうするのはまったく不要ですが、とにかくこのようなことをしようとしているようです。this関数が呼び出されているか構築されているかによってセマンティクスが変化するオブジェクトの代わりに、使用をやめて、実際のオブジェクトを制御下で使用することができます。

于 2012-08-30T05:14:48.010 に答える