Javascript 在Node.js中创建模块的副本,而不是实例

Javascript 在Node.js中创建模块的副本,而不是实例,javascript,node.js,object,module,instance,Javascript,Node.js,Object,Module,Instance,这将是我关于stackoverflow的第一个问题,希望进展顺利。 我一直在开发一个游戏(使用corona SDK),我使用Node.js编写了一个小型服务器来处理客户端之间的一些聊天消息,没有问题。 现在我正在扩展这个小服务器来做更多的事情,我想做的是创建一个外部文件(模块),它将保存一个对象,该对象具有代表我游戏“大厅”中一个房间所需的所有函数和变量,在这里两个人可以进入一个房间进行游戏,每次我有两个玩家准备好玩,我会为他们创建一个空房间的副本,然后在那个房间里初始化游戏。 所以我在我的主项

这将是我关于stackoverflow的第一个问题,希望进展顺利。 我一直在开发一个游戏(使用corona SDK),我使用Node.js编写了一个小型服务器来处理客户端之间的一些聊天消息,没有问题。 现在我正在扩展这个小服务器来做更多的事情,我想做的是创建一个外部文件(模块),它将保存一个对象,该对象具有代表我游戏“大厅”中一个房间所需的所有函数和变量,在这里两个人可以进入一个房间进行游戏,每次我有两个玩家准备好玩,我会为他们创建一个空房间的副本,然后在那个房间里初始化游戏。 所以我在我的主项目文件中有一个数组,其中每个单元格都是一个房间,我的计划是将我的模块导入该数组,然后我可以在特定的“房间”中初始化游戏,玩家可以玩,游戏可以继续,一切都会很好。。。但是main.js中的我的代码:

var new_game_obj = require('./room.js');

games[room_id] = new_game_obj();

games[room_id].users = [user1_name,user2_name];
现在,在my room.js中,我有一些类似的东西:

var game_logistics = {};

game_logistics.users = new Array();

game_logistics.return_users_count = function(){
    return game_logistics.users.length;
}

module.exports = function() {
    return game_logistics;
}
到目前为止一切都很好,而且这项工作还不错,我可以简单地说:

games[room_id].return_users_count()
我会得到0,1,2,当然这取决于有多少用户加入了这个房间。 一旦我打开一个新房间,问题就开始了,因为Node.js将引用我创建的模块,而不是它的副本。如果我现在创建一个新房间,即使我删除和/或删除了旧房间,它也将包含我已经更新的旧房间的所有信息,而不是新的洁净室。例如:

var new_game_obj = require('./room.js');

games["room_1"] = new_game_obj();
games["room_2"] = new_game_obj();

games["room_1"].users = ["yuval","lahav"];

_log(games["room_1"].return_user_count()); //outputs 2...
_log(games["room_2"].return_user_count()); //outputs 2...
即使这样做:

var new_game_obj = require('./room.js');
games["room_1"] = new_game_obj();

var new_game_obj2 = require('./room.js');
games["room_2"] = new_game_obj2();

games["room_1"].users = ["yuval","lahav"];

_log(games["room_1"].return_user_count()); //outputs 2...
_log(games["room_2"].return_user_count()); //outputs 2...
给出相同的结果,在我制作的所有“副本”中,它都是相同模块的相同实例。 所以我的问题就这么简单,我如何创建一个原始模块的“干净”副本,而不是一次又一次地实例化它,最终只剩下一个凌乱的房间?

您要做的就是这样(用返回的内容替换
require()
调用)

因此,每次调用
new\u game\u obj
,都会返回相同的
game\u logistics
实例

相反,您需要使
new_game_obj
返回
game_logistics
的新实例

// room.js
function Game_Logistics() {
    this.users = [];

    this.return_users_count = function(){
        return this.users.length;
    };
}

module.exports = function() {
    return new Game_Logistics(); 
}
这是一种心态上的转变。您将看到,我们在
模块中的
Game\u Logistics
上使用
new
。每次调用
Game\u Logistics
时,都会导出
以返回一个新的
Game\u Logistics
实例

您还将看到,在
游戏后勤
中,
这个
被到处使用,而不是
游戏后勤
;这是为了确保我们引用的是
Game\u Logistics
的正确实例,而不是构造函数

我还将您的
game\u logistics
函数大写,以遵守广泛遵循的命名约定,即构造函数函数应大写()


在处理多个函数实例时,建议使用JavaScript中的原型链。您可以阅读关于“javascript原型继承*(例如)”的各种文章,但现在,上面的内容将满足您的需要。

是的,学习如何正确使用
new
关键字并编写“正确”“javascript类而不是对象文本。查看一些关于您可以使用的选项以及它们的不同之处的讨论。感谢您提供的信息,这似乎很有效,很抱歉我的javascript不够“合适”,我来自actionscript/lua/php背景,尽管我过去习惯于使用javascript、html和xml,但我从来都不是“专家”,但是我在一些好人的帮助下学习,谢谢你的链接,我会尽快阅读的!)@尤瓦尔:不需要道歉,每个人都是“新”的:)@Jason谢谢你给我这篇文章的链接,它内容丰富,短小精悍,给了我我所缺少的信息。是的,当我学习这些东西的时候,它也帮了我的忙。我一开始是以文本形式编写对象,就像您在原始代码中所做的那样,我不完全理解如何使用原型策略,也不完全理解为什么我会用javascript编写一些复杂到需要它的东西(在我开始使用node之前)。使用这两种方法是有原因的,但随着时间的推移,我越来越清楚地认识到原型策略在很多时候更有用。
// room.js
function Game_Logistics() {
    this.users = [];

    this.return_users_count = function(){
        return this.users.length;
    };
}

module.exports = function() {
    return new Game_Logistics(); 
}