我已经构建了一个BaseModel类,我们所有的模型都继承自这个类。我遇到了一个问题,TestModel的新实例(下面)正在维护其他以前实例化的模型的属性。
这是为什么?我做错了什么?
var util = require('util');
var ModelBase = function(request, params, definition) {
this.request = request;
this.def = definition.schema ? definition.schema : {};
if(params && typeof params === 'object' && !Array.isArray()) {
this.set(params);
}
};
ModelBase.prototype.... // a lot more proto methods in ModelBase
// TestModel inherits from ModelBase
var TestModel = function(request, params) {
ModelBase.call(this, request, params, MOCK_MODEL_DEFINITION);
};
util.inherits(TestModel, ModelBase);
var mdl = new TestModel(MOCK_REQUEST, { a: 'A' });
var mdl2 = new TestModel(MOCK_REQUEST);
console.log(mdl.toObject()); // { a: 'A' }
console.log(mdl2.toObject()); // { a: 'A' } - should be empty
修改 :以下是我尝试过的其他一些不起作用的内容:
var TestModel = function(request, params) {
return new ModelBase(request, params, MOCK_MODEL_DEFINITION);
};
// move the base constructor logic to an init func
var TestModel = function(request, params) {
this.init(request, params, MOCK_MODEL_DEFINITION);
};
答案 0 :(得分:2)
问题是所有对象都从同一来源初始化其def
字段。 ModelBase
在TestModel
构造函数中调用ModelBase.call(this, request, params, MOCK_MODEL_DEFINITION);
:
def
所以在所有情况下 MOCK_MODEL_DEFINITION.schema
都设置为{ a: { validate: 'validation obj here' } }
的值,这是一个定义为TestModel
的对象,此对象的任何更改都将是由所有console.log(mdl.def === mdl2.def);
个对象共享。
可以通过在代码中添加以下测试来轻松测试:
true
这将显示mdl.def
。这表示mdl2.def
和def
不是两个对象,它们共享相同的值,但它们是相同的对象。
我看到两个解决方案
现在,您将用于验证数据的架构存储在与数据相同的结构中。您可以像现在一样在var ModelBase = function(request, params, definition) {
this.def = definition.schema ? definition.schema : {};
this.data = {};
this.set(params);
};
ModelBase.prototype.set = function(params) {
for(var p in params) {
this.data[p] = params[p];
}
};
中继续存储架构。但是您应该将数据存储到不同的字段中。例如:
def
如果你的模式是不可变的,那么分享它们就没有问题了。
def
您需要做的是通过创建初始化对象的副本来初始化this.def = definition.schema ? definition.schema : {};
。基本上,而不是:
this.def = definition.schema ? copy(definition.schema) : {};
你需要这个:
copy
其中{{1}}是适用于您的案例的任何复制操作。以下是涵盖执行浅层和深层复制的最佳方法的好问题: