使用逻辑加载对象

Load object with logic

我相信我的问题的解决方案相对容易。我就是没看到。

我有一个对象:

function MyObject(){
  this.attr = "anything";
}

MyObject.prototype.doSomething = function(){
   // logic
}

我使用 new MyObject() 创建对象。我使用它,当我想退出我所做的事情时,我只是将它存储到数据库中 (mongodb)。在mongo中是这样存储的:

{ "attr" : "anything" }

当我从数据库加载对象时,我只有没有任何逻辑的普通对象文字。缺少方法。我明白为什么 ;) 但我不知道如何再次将逻辑添加到对象文字中...

问题

如何再次用原始逻辑装饰检索到的对象?让它再次看起来像这样:

{       
  "attr" : "anything",
  "doSomething": doSomething()
} 

您可以使用 Object.create to create an object from the prototype without calling the constructor, and then use Object.assign 将您检索到的对象的属性分配给新创建的对象:

var fullObject = Object.assign( Object.create( MyObject.prototype ), retrievedObject );

示例:

function MyObject(){
  this.attr = "anything";
}

MyObject.prototype.doSomething = function(){
  document.body.innerHTML = this.attr;
}

// Plain object retrieved from database
var retrievedObject = {       
  "attr" : "foobar"
};

// Object with proper prototype and properties
var myObject = Object.assign( Object.create( MyObject.prototype ), retrievedObject );

myObject.doSomething();

创建一个加载函数,将您获取的对象的所有属性加载回您自己的对象中。

您可以访问您的对象 属性 名称作为关联数组索引。

所以 myobj.attrmyobj['attr'] 相同。

这有助于将数据动态插入对象,同时保持对数据的完全控制(我个人最喜欢的):-)

您可以添加一些额外的检查来防止多余的数据或做一些额外的事情,随心所欲。例如修改时间戳。

function MyObject(data){
  if(typeof data !== 'undefined') {
     this.load(data);
  }
  else {
      this.attr = "anything";
  }
}

MyObject.prototype.doSomething = function(){
   // logic
}
MyObject.prototype.load = function(data) {
   for(var key in data) {
      if(data.hasOwnProperty(key)) { 
        this[key] = data[key];
        // Just sample validation check. wahtever you want.
        if(key == 'timestamp') {
             if(this[key] < new Date().getTime()-4000) {
                  this[key] = new Date().getTime();
             }
        }
      }
   }
}

@paulpro 的回答的扩展,我不得不稍微修改这段代码 Object.create( MyObject.prototype )。当我以这种方式使用继承对象时,它没有正确实例化 private 成员。我只是将 Object.create( MyObject.prototype ) 替换为 new MyObject()。就是这样。

2016 年 5 月 3 日更新

最安全的方法是使用lodash's assing

var objectWithLogic = _.assign(new MyObject(), data);