在Node.js中,我是在“需要”时创建一个新对象吗?

问题描述 投票:24回答:2

所以,我不确定的是。如果在ModuleA中,我有:

var mongoose = require('mongoose');
mongoose.connect(pathA);

在ModuleB中,我有:

var mongoose = require('mongoose');
mongoose.connect(pathB);

在主程序中,我有:

var mA = require('./moduleA.js'), 
mB = require('./moduleB.js');

所以,当我运行主程序时,我想我会创建两个猫鼬“实例”;一个连接到pathA,一个连接到pathB,是吗?

另外,在模块B中,在连接到pathB之前,它是否连接到pathA或什么都没有?

谢谢。

node.js require mongoose
2个回答
16
投票

我刚用最新的节点V0.4.6进行了几次测试。我确认了以下内容:

  1. 从“require”返回的变量是单例。
  2. 后续更改将在包含它的所有其他模块中更改所需模块的数据。
  3. 猫鼬的联系有点奇怪。即使断开连接并将其设置为新的连接路径,它仍然使用旧的连接路径。

所以,我的意思是上述第1点和第2点是:

如果你有模块大师:

var myStr = 'ABC';
module.exports.appendStr = function(data) {
    myStr += ' ' + data;    
};
module.exports.output = function() {
    console.log("Output: " + myStr);
};

如果你有另外两个模块:

模块A.

var mc = require('./moduleMaster.js');
var ma = function() {mc.appendStr(' MA '); };
ma.prototype.output = function() {
  mc.output();
}
module.exports.create = function() {
    return new ma();
};

module.exports._class = ma;

模块B.

var mc = require('./moduleMaster.js');
var mb = function() {mc.appendStr(' MB '); };
ma.prototype.output = function() {
  mc.output();
}
module.exports.create = function() {
    return new mb();
};

module.exports._class = mb;

现在,当您运行需要模块A和模块B的测试脚本时,实例化它们并输出:

mTestA.output();
mTestB.output();

您将获得以下输出:

ABC MA
ABC MA MB

代替

ABC MA
ABC MB

因此,它是一个单身人士。不仅仅是本地模块。


3
投票

我遇到过这篇文章,虽然接受的答案显示它是一个Singleton,但我对原始问题的回答“在Node.js中,我是否在”需要“时创建一个新对象?”是“它取决于”。

murvinlai的答案/逻辑仍然适用于最新版本的Node(截至本文撰写时的v0.10.18),但是如果你以这种方式设置了所需的文件。例如,如果你在User.js中有以下“用户”代码(结构与murvinlai的答案不同),我试图使用一个更详细的例子来避免任何混淆

/**
 * User Model
 */
function modelUser() {
    var User  = {
        /**
         * User::_id
         *
         * @var integer
         */
        "_id" : null,

        /**
         * Set id
         *
         * @param integer id
         * @return User
         */
        "setId" : function(id)
        {
            User._id = id; 
            return User;
        },

        /**
         * Get id
         *
         * @return integer
         */
        "getId" : function()
        {
            return User._id;
        },

    }

    return User;

}
exports.modelUser = modelUser;

现在,如果您使用上面的代码,您可能会发现在许多情况下没有修改您将不会遇到Singleton问题。 IE用:

var user1 = require("./application/models/User.js").modelUser(); // In one module
var user2 = require("./application/models/User.js").modelUser(); // In another module

user1.setId(1);

console.log(user1.getId());
console.log(user2.getId());

你会得到1,null。另外,我甚至不确定你是否需要这个,但你可以在require上使用new运算符(因为它实际上只是返回一个函数)。 IE用:

var user1 = new require("./application/models/User.js").modelUser(); // In one module
var user2 = new require("./application/models/User.js").modelUser(); // In another module

user1.setId(1);

console.log(user1.getId());
console.log(user2.getId());

你会得到相同的输出。

同样,最初的问题有点宽泛(蚂蚁问题可能最终与mongoose有关(如murvinlai的回应#3中提到的),但上面是另一种做事的例子,以产生一个实际的新对象关闭每个require()的内容。现在你可能想在做这个之前想一想,有时你会想要Singleton(比如在ORM / Mapper中存储缓存的值),但最后你要创建一个新的对象,它取决于..

© www.soinside.com 2019 - 2024. All rights reserved.