web-dev-qa-db-ja.com

javascriptプレーンオブジェクトをモデルクラスインスタンスに変換します

小さなODMのような機能を実装する必要があります。データベースからプレーンなJavaScriptオブジェクトを取得し、それをモデルクラスインスタンスに変換する必要があります。モデルが次のようになっていると仮定しましょう。

_    class Model{
       constructor(){
           this.a = '777';
           ---- whole bunch of other things ---
       }
       print(){
           console.log(this.a);
       }
   }
_

したがって、_var a = {b:999, c:666}_をモデルのインスタンスに変換し、a.print()を呼び出すことができるようにする必要があります。また、a.print()が実行されると、_777_をコンソールに配置する必要があります。どうやってするか?

15
silent_coder

簡単な方法があります。オブジェクトをinstance(this)に割り当てるだけです

class Model
{
  constructor(obj){
    Object.assign(this, obj)
  }
  print(){
    console.log(this.a);
  }
}

let obj = {a: 'a', b: 'b', c: 'c'}
    
let m = new Model(obj)
console.log(m)
m.print()  // 'a'
11
junlin

質問を正しく理解していれば、ファクトリ関数をエクスポートし、Object.assignを使用してベースModelを拡張できます。

// Export the factory function for creating Model instances
export default const createModel = function createModel(a) {
  const model = new Model();
  return Object.assign(model, a);
};
// Define your base class
class Model {
  constructor() {
    this.a = 777;
  }
  print() {
    console.log(this.a, this.b, this.c)
  }
}

そしてそれを次のように呼びます:

const myModel = createModel({ b: 999, c: 666 });
myModel.print();

Babel REPL例

または、もちろん、ファクトリを放棄してaをパラメーター(または残りのパラメーター)としてコンストラクターに渡すこともできますが、それは好みのコーディングスタイルによって異なります。

3
CodingIntrigue

G_hi3の答えと同じですが、プロパティオブジェクトの作成を「自動化」します。

function Model() {
  this.a = '777';
}

Model.prototype.print = function(){
    console.log(this.a);
}

   // Customize this if you don't want the default settings on the properties object.
function makePropertiesObj(obj) {
    return Object.keys(obj).reduce(function(propertiesObj, currentKey){
        propertiesObj[currentKey] = {value: obj[currentKey]};
        return propertiesObj;
    }, {}); // The object passed in is the propertiesObj in the callback
}

var data = {a: '888'};

var modelInstance = Object.create(Model.prototype, makePropertiesObj(data));
// If you have some non trivial initialization, you would need to call the constructor. 
Model.call(modelInstance);
modelInstance.print(); // 888
0
Juan Mendes

これはどう?:

var a = Object.create(Model.prototype, {
    b: {
        enumerable: true, // makes it visible for Object.keys()
        writable: true, // makes the property writable
        value: 999
    }, c: {
        value: 666
    }
});

基本的に、プロトタイプからModelの新しいインスタンスを作成し、それに新しいプロパティを割り当てます。 printも呼び出すことができるはずです。

0
G_hi3

すべてのプロパティを単一のJSオブジェクトthis.propsに格納し、このオブジェクトをコンストラクターで受け入れるようにクラスを書き直すことをお勧めします。

class Model {
  constructor (props = this.initProps()) {
    this.props = props
    // other stuff
  }
  initProps () {
    return {a: '777'}
  }
  print () {
    console.log(this.props.a)
  }
}

次に、this.propsをプレーンなJSオブジェクトとしてデータベースに保存し、それを使用して対応するクラスインスタンスを簡単に再作成できます。

new Model(propsFromDatabase)

ただし、すべてのプロパティをthis.propsに移動したくない場合は、Object.assignを使用してオブジェクトをわかりやすくすることができます。

class Model {
  constructor (props = this.initProps()) {
    Object.assign(this, props)
    // other stuff
  }
  initProps () {
    return {a: '777'}
  }
  print () {
    console.log(this.props.a)
  }
}

ただし、名前の衝突から安全に保つため、前者のアプローチを使用することをお勧めします。

0