2

I have a constructor object that has various fields; For a simple example, say

function Person(id, name) {
  this.id = id;
  this.name = name;
  etc.
  this.someFunction = function(xxx) {...}
}

Now, I have an arbitrary object with an id and name field

var somePerson = {id:123, name:"joe"}

I would like to inject the data from the somePerson instance into a Person constructor, so I can apply all of the methods from the Person class, but I am confused between apply, call, and bind.

I am aware that I can call a new constructor passing in all of the fields, but there are a lot of fields. Is there any easy way to just endow the somePerson instance with the methods from the Person class?

Vinny Gray
  • 277
  • 2
  • 15

5 Answers5

1

I think you got it wrong, what you are trying to do is :

var somePerson = new Person(123, 'joe');

then you will be able to write :

somePerson.someFunction();
jony89
  • 3,706
  • 2
  • 22
  • 36
1

You need to create a new Person instance, there's no need to use call or apply.

var somePerson = {id:123, name:"joe"};
var somePersonInstance = new Person(somePerson.id, somePerson.name);
somePersonInstance.someFunction(xxx);

You could have used call if the method was not inside the constructor, but on the prototype:

function Person(id, name) {
  this.id = id;
  this.name = name;
}
Person.prototype.someFunction = function(xxx) {…};

var somePerson = {id:123, name:"joe"};
Person.prototype.someFunction.call(somePerson, xxx);
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
1

You could use Object.assign() and assign properties of somePerson object to instance of Person

function Person(id, name) {
  this.id = id;
  this.name = name;
  this.someFunction = function() {
    return this.name;
  }
}

var somePerson = {id:123, name:"joe"}
var p = Object.assign(new Person, somePerson)

console.log(p.someFunction())
Nenad Vracar
  • 102,378
  • 14
  • 116
  • 136
  • did you mean var p = Object.assign(new Person(), somePerson) – Vinny Gray Jan 10 '17 at 16:57
  • You can omit parenthesis if you are not going to supply arguments. – Nenad Vracar Jan 10 '17 at 16:58
  • 1
    The problem with this solution is that it doesn't work with constructors that *require* their arguments. I'd recommend to always use a class-specific helper methods, such as `Person.fromJSON` (that knows how/whether to call its constructor). – Bergi Jan 10 '17 at 17:00
0

Sure How's this;

function PersonFactory(id, name) {
    return {
        id: id,
        name: name,
        updateName: function(name)  {
            this.name = name
        }
    }
}

Some exmaples of it being used.

var somePerson = PersonFactory(1, "Luke")

var people = {
    luke: PersonFactory(1, "Luke"),
    will: PersonFactory(2, "Will"),
    smith: PersonFactory(3, "Smith")
}

var persons = [
PersonFactory(1, "Luke"),
PersonFactory(1, "Will"),
PersonFactory(1, "Smith")
]

people.luke.updateName("Harry");
0

Person is set up like a constructor function. You need to use the new keyword to instantiate a new copy of Person.

var joe = new Person(somePerson.id, somePerson.name);

Now joe will be an instance of Person.

joe instanceof Person //true
joe.id //123
joe.someFunction //function (xxx) {...}
Zanchi
  • 3
  • 3