我使用以下问题作为我的应用程序的设备对象的指南: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 <--????
设备1对象似乎被覆盖 - 为什么会发生这种情况?
这是根据@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。
最佳答案
Node 模块像单例一样工作。当您需要模块时, Node 不会创建新对象,而是返回相同的对象,因此在这种情况下两个实例都使用相同的模型。
您可以使用以下条件进行测试:
device1.model === device2.model // should return `true`
device1 === device2 // should return `false`, 2 different instances
How would I get around this?
要拥有独特的模型(对象),您有多种选择:
导出工厂函数
您可以定义一个返回对象的函数:
module.exports = function() {
return { ... };
}
现在您可以请求该模块并调用导出的函数。
var newModel = require('path/to/module')();
Clone the object
另一个选项是克隆对象。以下代码片段使用 ECMAScript2015 的 Object.assign
创建对象的浅拷贝。
var clonedModel = Object.assign({}, model);
关于node.js - 为什么新的对象构造函数会覆盖以前的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40754647/