3

我认为我严重误解了如何使用 module.exports。似乎每个模块都在覆盖最后一个吐出的内容。

应用程序.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);(相同的)

模块A.js

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

模块B.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引用全局对象。所以当然从两个位置修改全局对象会互相覆盖,返回this只会返回全局对象。您可以自己测试:使用您当前的代码,

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

防止自己再次像这样在脚上射击自己的一种方法是使用严格模式而不是马虎模式。为此,请添加行

"use strict";

在您编写的每个模块的顶部(在任何其他代码之前)。在严格模式下,对于没有isthis调用的构造函数,你会得到一个更早且更容易理解的错误。newundefined

严格模式有很多这样的好处;有关概述,请参见[1][2][3]


另一种解决方案是完全停止使用构造函数,而是使用工厂函数。这看起来像:

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

无论如何,您似乎都在尝试做这样的事情,因为return this即使在构造函数中这样做也是完全没有必要的。您可以停止使用this并使用您控制下的实际对象,而不是根据您的函数是被调用还是构造而改变语义的对象。

于 2012-08-30T05:14:48.010 回答