为什么新的对象构造函数会覆盖前一个对象?

时间:2016-11-23 01:35:13

标签: node.js

我使用以下问题作为我的应用程序的Device对象的指南:Node.js - use of module.exports as a constructor,但似乎创建的第一个对象被后续对象构造函数覆盖。

我的目标文件(MyDevice.js)如下:

function Device(port) {
  // Load the default device model from JSON file
  var model = require(SomeJSONFile);

  // Update port in the model
  model.port = port;

  // Update object's model    
  this.model = model;
}

Device.prototype.GetPort = function () { 
  return this.model.port;
}

module.exports = Device;// Export

在我的应用程序(test.js)中,我创建对象并打印结果:

var Device = require("./devices/MyDevice.js");
var device1 = new Device(1);
console.log("device1 port=" + device1.GetPort());
var device2 = new Device(2);
console.log("device2 port=" + device2.GetPort());
console.log("device1 port=" + device1.GetPort());

我不确定为什么会得到以下输出:

> node test.js
device1 port=1
device2 port=2
device1 port=2 <--????

看来device1对象被覆盖 - 为什么会发生这种情况?

以下是基于@ undefined答案的修改后的代码:

我的目标文件(MyDevice.js):

function Device(port) {
  // Load the default device model from JSON file
  var model = require(SomeJSONFile);
  this.model = JSON.parse(JSON.stringify(model));// 'Unique-ify' model
  this.model.port = port;// Set model parameter(s)
}

Device.prototype.GetPort = function () { 
  return this.model.port;
}

// Export factory function
module.exports = function(port) {
  return new Device(port)
}

我的申请(test.js):

var device1 = require("./devices/MyDevice.js")(1);// Call factory function with port=1
console.log("device1 port=" + device1.GetPort());
var device2 = require("./devices/MyDevice.js")(2);// Call factory function with port=2
console.log("device2 port=" + device2.GetPort());
console.log("device1 port=" + device1.GetPort());

device2不再覆盖device1 - 输出为:

device1 port=1
device2 port=2
device1 port=1

device1!= device2,由于克隆了模型,device1.model!= device2.model。

1 个答案:

答案 0 :(得分:4)

节点模块像单身人士一样工作。当您需要模块时,节点不会创建新对象,它会返回相同的对象,因此在这种情况下,两个实例都使用相同的模型。

您可以使用以下条件对此进行测试:

device1.model === device2.model // should return `true`   
device1 === device2 // should return `false`, 2 different instances
  

我如何解决这个问题?

要拥有独特的模型(对象),您有以下几种选择:

导出工厂功能

您可以定义一个返回对象的函数:

module.exports = function() {
   return { ... };
}

现在您可以要求模块并调用导出的函数。

var newModel = require('path/to/module')();

Clone the object

另一种选择是克隆对象。以下代码段使用ECMAScript2015 Object.assign创建对象的浅表副本。

var clonedModel = Object.assign({}, model);