我使用以下问题作为我的应用程序的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。
答案 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')();
另一种选择是克隆对象。以下代码段使用ECMAScript2015 Object.assign
创建对象的浅表副本。
var clonedModel = Object.assign({}, model);