在Node.js中创build一个模块的副本,而不是一个实例

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

var new_game_obj = require('./room.js'); games[room_id] = new_game_obj(); games[room_id].users = [user1_name,user2_name]; 

现在,在我的房间里,我有这样的东西:

 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,这当然取决于有多less用户join了这个房间。 一旦我打开一个新的房间,问题就开始了,因为Node.js会将我创build的模块实例化,而不是复制它,如果我现在创build一个新房间,即使我删除和/或删除旧房间,它会提供我已经更新的旧房间的所有信息,而不是一个新的洁净室。 例:

 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... 

给出相同的结果,它是在我所做的所有“副本”中的相同模块的所有相同的实例。 所以我的问题就这么简单,我该如何创build一个原始模块的“干净的”副本,而不是一遍又一遍地实例化,最后实际上只有一个凌乱的房间?

你在做什么是(取代你的require()调用返回的东西);

 var new_game_obj = function() { return game_logistics; } 

所以,每次你调用new_game_obj ,你都会返回相同game_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_Logistics中的module.exports上使用newGame_Logistics module.exports时返回一个新的实例。

你也可以在Game_Logistics里面看到这个,而不是Game_Logistics ; 这是为了确保我们引用Game_Logistics的正确实例 ,而不是构造函数。

我也已经大写了你的game_logistics函数来遵守广泛遵循的命名约定,即构造函数应该被大写( 更多信息 )。

当您使用多个函数实例时,build议利用JavaScript中的原型链。 你可以仔细阅读“javascript原型inheritance*(例如这一个 )的各种文章,但现在,上述将完成你所需要的。