简体   繁体   English

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

[英]Create a copy of a module instead of an instance in Node.js

this would be my first question ever on stackoverflow, hope this goes well. 这将是我关于stackoverflow的第一个问题,希望一切顺利。 I've been working on a game (using corona SDK) and I used Node.js to write a small little server to handle some chat messages between my clients, no problems there. 我一直在开发游戏(使用corona SDK),并使用Node.js编写了一个小型服务器来处理客户端之间的一些聊天消息,那里没有问题。 Now I'm working on expanding this little server to do some more, and what I was thinking to do is create an external file (module) that will hold an object that has all the functions and variables I would need to represent a Room in my games "Lobby", where 2 people can go into to play one against the other, and each time I have 2 players ready to play, I would create a copy of this empty room for them, and then initialize the game in that room. 现在,我正在努力扩展这台小型服务器,以执行更多操作,而我正在考虑做的是创建一个外部文件(模块),该文件将容纳一个对象,该对象具有表示我在其中的Room所需的所有功能和变量。我的游戏“大厅”,两个人可以进场比赛,每当我有2个玩家准备比赛时,我将为他们创建一个空房间的副本,然后在该房间中初始化游戏。 So I have an array in my main project file, where each cell is a room, and my plan was to import my module into that array, and then I can init the game in that specific "room", the players would play, the game will go on, and all would be well... but... my code in main.js: 所以我在主项目文件中有一个数组,其中每个单元是一个房间,我的计划是将模块导入到该数组中,然后我可以在该特定“房间”中初始化游戏,玩家可以玩,游戏将继续进行,一切都会很好...但是...我在main.js中的代码:

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

games[room_id] = new_game_obj();

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

Now, in my room.js, I have something of the sort: 现在,在我的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;
}

So far so good, and this work just fine, I can simply go: 到目前为止,一切顺利,而且一切正常,我可以简单地进行以下操作:

games[room_id].return_users_count()

And I will get 0, or 1, or 2, depending of course how many users have joined this room. 我将得到0或1或2,具体取决于加入该会议室的用户数量。 The problems starts once I open a new room, since Node.js will instance the module I've created and not make a copy of it, if I now create a new room, even if I eliminated and/or deleted the old room, it will have all information from the old room which I've already updated, and not a new clean room. 一旦我打开一个新房间,问题就开始了,因为Node.js将实例化我创建的模块,而不是对其进行复制,即使现在我创建一个新房间,即使我删除和/或删除了旧房间,它会包含我已经更新的旧房间的所有信息,而不是新的洁净室的信息。 Example: 例:

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

Even doing this: 即使这样做:

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

Gives the same result, it is all the same instance of the same module in all the "copies" I make of it. 给出相同的结果,它是我制作的所有“副本”中同一模块的所有相同实例。 So my question as simple as that, how do I create a "clean" copy of my original module instead of just instancing it over and over again and actually have just one messy room in the end? 所以我的问题就这么简单,我如何创建原始模块的“干净”副本,而不是一遍又一遍地实例化它,实际上最后只有一个凌乱的房间?

What you're doing is this (replacing your require() call with what gets returned); 您正在执行的操作是(用返回的内容替换require()调用);

var new_game_obj = function() {
    return game_logistics;
}

So, every time you call new_game_obj , you return the same instance of game_logistics . 因此,每次调用new_game_obj ,都将返回相同game_logistics实例。

Instead, you need to make new_game_obj return a new instance of 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(); 
}

This is quite a shift in mentality. 这是一种观念上的转变。 You'll see that we're using new on Game_Logistics in module.exports to return a new instance of Game_Logistics each time it's called. 你会看到,我们正在使用newGame_Logisticsmodule.exports返回的实例Game_Logistics每次它被称为时间。

You'll also see that inside Game_Logistics , this is being used everywhere rather than Game_Logistics ; 您还将看到,在Game_Logistics内部, this已被广泛使用,而不是Game_Logistics this is to make sure we're referencing the correct instance of Game_Logistics rather than the constructor function. 这是为了确保我们引用的是Game_Logistics的正确实例 ,而不是构造函数。

I've also capitalized your game_logistics function to adhere to the widely-followed naming convention that constructor functions should be capitalized ( more info ). 我还大写了您的game_logistics函数,以遵守广泛遵循的命名约定,即构造函数应大写( 更多信息 )。

Taking advantage of the prototype chain in JavaScript is recommended when you're working with multiple instances of functions. 当您使用多个函数实例时,建议利用JavaScript中的原型链。 You can peruse various articles on "javascript prototypical inheritance* (eg this one ), but for now, the above will accomplish what you need. 您可以阅读有关“ JavaScript原型继承*(例如, 这一篇 )”的各种文章,但是到目前为止,以上内容可以满足您的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM