【问题标题】:In Node.js, am I creating a new object when "Require"?在 Node.js 中,我是否在“需要”时创建了一个新对象?
【发布时间】:2011-08-13 06:59:05
【问题描述】:

所以,我不确定的是。如果在 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


    【解决方案1】:

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

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

    那么,我所说的上述第 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
    

    因此,它是一个单例。不仅仅是模块的本地。

    【讨论】:

      【解决方案2】:

      我看到了这篇文章,虽然接受的答案显示它是一个单例,但我对原始问题的回答是“在 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 问题。浏览器:

      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());
      

      你会得到相同的输出。

      同样,最初的问题有点宽泛(问题可能最终与猫鼬有关(如 murvinlai 的回应中的#3 中所述),但以上是另一种方法的示例,以产生每个 require() 的实际新对象。现在您可能需要在执行此操作之前考虑一下,因为有时您需要 Singleton(例如将缓存值存储在 ORM/Mapper 中),但最后是您创建一个新对象,这取决于..

      【讨论】:

      • 好点。值得一提的是,这种在 Javascript 中创建对象的方法比使用“原型”方法要慢,因为 V8 无法区分同一“类”的两个不同实例。更多详情,请点击此处:thenodeway.io/posts/designing-custom-types
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2018-08-03
      相关资源
      最近更新 更多