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