2

I used the following question as a guide for my application's Device object: Node.js - use of module.exports as a constructor, but it appears that the first object created is overwritten by a subsequent object constructor.

My object file (MyDevice.js) is as follows:

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

In my application (test.js), I do create the objects and print the results:

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

I'm not sure why I get the following output:

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

It appears that the device1 object is overwritten - why would this happen?


Here is the modified code based on @undefined's answer:

My object file (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)
}

My application (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 no longer overwrites device1 - the output is:

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

device1 != device2 and because of cloning of the model, device1.model != device2.model.

Community
  • 1
  • 1
HiDefLoLife
  • 555
  • 1
  • 8
  • 28

1 Answers1

4

Node modules work like singletons. When you require a module, node doesn't create a new object, it returns the same object, so in this case both instances use the same model.

You can test this by using the following conditions:

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

How would I get around this?

For having unique models (objects), you have several options:

Export a factory function

You can define a function that returns an object:

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

Now you can require the module and call the exported function.

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

Clone the object

Another option is cloning the object. The following snippet uses ECMAScript2015's Object.assign which creates a shallow copy of the object.

var clonedModel = Object.assign({}, model);
Community
  • 1
  • 1
Ram
  • 143,282
  • 16
  • 168
  • 197