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

时间:2014-04-04 14:19:01

标签: javascript node.js object module instance

这将是我在stackoverflow上的第一个问题,希望这很顺利。 我一直在开发游戏(使用电晕SDK),我使用Node.js编写一个小型服务器来处理客户端之间的聊天消息,没有任何问题。 现在我正在努力扩展这个小服务器以做更多工作,我想要做的是创建一个外部文件(模块),它将包含一个对象,该对象具有我需要表示的所有函数和变量在我的游戏中的房间" Lobby",其中2个人可以相互竞争,每次我有2个玩家准备玩,我会为他们创建这个空房间的副本,并且然后在那个房间初始化游戏。 所以我在我的主项目文件中有一个数组,每个单元格都是一个房间,我的计划是将我的模块导入到该数组中,然后我就可以在特定的#34; room"中启动游戏,玩家会玩,游戏会继续,一切都会好......但是......我的代码在main.js中:

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

games[room_id] = new_game_obj();

games[room_id].users = [user1_name,user2_name];

现在,在我的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...

给出相同的结果,它是所有"副本中的相同模块的所有相同实例"我做到了。 所以我的问题很简单,如何创建一个" clean"我的原始模块的副本,而不是一遍又一遍地实例化,实际上最后只有一个凌乱的房间?

1 个答案:

答案 0 :(得分:1)

你正在做的是这个(用返回的内容替换你的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(); 
}

这是心态的转变。您会看到我们在new的{​​{1}}上使用Game_Logistics,每次调用module.exports时都会返回新的实例。< / p>

您还会看到Game_Logistics内,Game_Logistics被用于所有地方,而不是this;这是为了确保我们引用Game_Logistics的正确实例而不是构造函数。

我还将您的Game_Logistics函数大写,以遵循广泛遵循的命名约定,即构造函数应该大写(more info)。

当您使用多个函数实例时,建议您利用JavaScript中的原型链。您可以仔细阅读有关“javascript原型继承*(例如this one)的各种文章,但就目前而言,上述内容将满足您的需求。