-2

Most guides on JavaScript explain object creation using constructor functions as follows:

let Person = function (fn, ln) {
    this.fn = fn;
    this.ln = ln;
};
Person.prototype.greet = function () {
    console.log("hello "+ this.fn+ " "+ this.ln)
};

That is: fields are defined in the constructor function while methods are added to the prototype.

Now I understand that the properties defined inside the constructor function will form N copies for N instances, while those on the prototype will have 1 copy shared among all N instances. So it makes sense that properties are defined inside the constructor, as we obviously don't want the copies to be sharing mutable properties like arrays etc.

What I don't get is why the methods aren't defined in the constructor function too. Like this:

let Person = function (fn, ln) {
    this.fn = fn;
    this.ln = ln;
    this.greet = function () {
       console.log("hello "+ this.fn+ " "+ this.ln)
    };
};

I understand that it will result in there being a copy for each instance and the methods belonging to the object itself rather than its parent/prototype, but is there any particular downside to it?

It just seems a lot more coherent and similar to Ruby etc. style-wise.

Nayuki
  • 17,911
  • 6
  • 53
  • 80
Warrshrike
  • 126
  • 1
  • 8
  • Hint: if I do `Person('a','b').greet()` what does `this` refer to during execution of `greet`? – dtanders Feb 29 '16 at 19:29
  • It would certainly be easier to repurpose the function stored in `Person.prototype.greet` than it would be for the one defined inside the constructor. – Kevin B Feb 29 '16 at 19:30
  • Can you elaborate on how it would be easier to repurpose the function in prototype.greet? So you're saying that properties set inside the constructor function aren't inherited when `Person`'s prototype is set to a child class? – Warrshrike Feb 29 '16 at 19:47
  • i mean, `someotherconstructor.prototype.greet = Person.prototype.greet` is easier than `someotherconstructor.prototype.greet = new Person().greet` in that it wouldn't require creating an instance to access/override the function. – Kevin B Feb 29 '16 at 19:48
  • Look at it this way. You an do it either way, and there are workarounds to accomplish whatever goals you want with both solutions. You've already mentioned the primary issue of defining the functions in the constructor, if that's not an issue to you then do it. – Kevin B Feb 29 '16 at 19:51
  • Makes sense. One last question: if I make a class `Kevin` and make it inherit from `Person` as follows `Kevin.prototype = Object.create(Person.prototype)`, then `Kevin` only gets the properties defined on the prototype and NOT those inside the constructor right? – Warrshrike Feb 29 '16 at 20:01
  • Right. if you wanted it to have the ones in the constructor you would have to create a `Person` instance inside the `Kevin` constructor and make them available. or, call the `Person` constructor on the `Kevin` instance. `Person.call(this, fn, ln)` – Kevin B Feb 29 '16 at 20:02
  • Yeah I guess I was trying to find the 'proper' way to do things in JS whereas its really flexible unlike other OO languages. Thanks a lot man. – Warrshrike Feb 29 '16 at 20:06
  • Since you seem to have access to some ES6 functionality, look into the new [Class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) functionality (which is really just syntactic sugar on top of what you're already doing) – Kevin B Feb 29 '16 at 20:08
  • Definitely I use those on ES6 with Traceur. I'm freshening up on this stuff in anticipation to learn NodeJs. – Warrshrike Feb 29 '16 at 20:51

1 Answers1

1

because if we defined methods in the constructor , a new Function object would be created for every object even though the method has the same code .

data members of the object are a different thing because they are supposed to carry data unique to every object.

Ramanlfc
  • 8,283
  • 1
  • 18
  • 24