为什么这个javascript obj的新实例继承了其他实例属性?

时间:2014-02-12 19:43:53

标签: javascript node.js oop inheritance

我已经构建了一个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);
};

1 个答案:

答案 0 :(得分:2)

问题是所有对象都从同一来源初始化其def字段。 ModelBaseTestModel构造函数中调用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.defdef不是两个对象,它们共享相同的值,但它们是相同的对象

我看到两个解决方案

将架构与数据分离

现在,您将用于验证数据的架构存储在与数据相同的结构中。您可以像现在一样在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}}是适用于您的案例的任何复制操作。以下是涵盖执行浅层和深层复制的最佳方法的好问题: