Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert javascript plain object into model class instance

I need to implement small ODM like feature. I get plain javascript object from database, and I need to convert it into my model class instance. Let's assume model looks like:

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

So I need convert var a = {b:999, c:666} to instance of model and being able to call a.print() after, and when a.print() executed 777 should be placed in console. How to do that?

like image 210
silent_coder Avatar asked Nov 18 '15 11:11

silent_coder


People also ask

How do you convert an object in JavaScript?

Use the JavaScript function JSON. parse() to convert text into a JavaScript object: const obj = JSON. parse('{"name":"John", "age":30, "city":"New York"}');

How do you create an instance in JavaScript?

An instance is an object containing data and behavior described by the class. The new operator instantiates the class in JavaScript: instance = new Class() . const myUser = new User(); new User() creates an instance of the User class.

What are plain JavaScript objects?

In vanilla JavaScript a POJO (Plain Old JavaScript Object) is the simplest kind of object you could possibly have: a set of key-value pairs, created by the {} object literal notation or constructed with new Object() .

Can we create object without constructor in JavaScript?

Yes. Show activity on this post.


4 Answers

There have a simple method. Just assign the object to 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'
like image 156
junlin Avatar answered Oct 11 '22 13:10

junlin


If I understand the question correctly, you can export a factory function and make use of Object.assign to extend your base 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)   } } 

And call it like:

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

Babel REPL Example

Or, of course, you could forego the factory and pass a in as a parameter (or rest parameters) to the constructor but it depends on your preferred coding style.

like image 21
CodingIntrigue Avatar answered Oct 11 '22 13:10

CodingIntrigue


I would suggest rewriting your class to store all its properties in a single JS object this.props and accept this object in its constructor:

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

Then you'll be able to store this.props in your database as a plain JS object and then use it to easily recreate corresponding class instance:

new Model(propsFromDatabase)

Though, if you don't want to move all properties to this.props, you could use Object.assign to keep your object plain:

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

But I would recommend using the former approach, because it'll keep you safe from name collisions.

like image 35
Leonid Beschastny Avatar answered Oct 11 '22 11:10

Leonid Beschastny


How about this?:

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
    }
});

You'd be basically creating a new instance of Model from it's prototype and assigning your new properties to it. You should be able to call print as well.

like image 41
G_hi3 Avatar answered Oct 11 '22 13:10

G_hi3