微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – module.exports在node.js应用程序中发生冲突/被覆盖

我想我很难误解如何使用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); (还打印“酒吧”)

有人可以解释我做错了吗?我想不出有任何其他方法可以做到这一点,因为导出助手(?)本身似乎不接受参数.

解决方法:

您正在导出构造函数.你需要构建它,而不是调用它.

更改

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

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

或(为清楚起见)

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

您所看到的是在sloppy模式下将构造函数作为函数调用时的常见行为:它引用了全局对象.因此,当然从两个位置修改全局对象将相互覆盖,并且返回它将只返回全局对象.您可以自己测试:使用您当前的代码,

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

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

"use strict";

在您编写的每个模块的顶部(在任何其他代码之前).在严格模式下,对于没有new的构造函数,这是未定义的,因此您将获得更早且更容易理解的错误.

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐