5

I was trying to understand OOP model of JavaScript, so I was reading this article: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

The following code was interesting:

function Person(gender) {
    this.gender = gender;
    alert('Person instantiated');
}

Person.prototype.gender = '';
var person1 = new Person('Male');
var person2 = new Person('Female');
//display the person1 gender
alert('person1 is a ' + person1.gender); // person1 is a Male

What was interesting and not clear to me is this line:

Person.prototype.gender = '';

I didn't understand so I tested the code both with that line and without it.

The code is working fine in both conditions.

So my question is:

Why did the author add that line?

toniedzwiedz
  • 17,895
  • 9
  • 86
  • 131
stackunderflow
  • 3,811
  • 5
  • 31
  • 43
  • 2
    In this case it's unnecessary. But imagine what it would do if the `this.gender = gender;` was omitted (or maybe wrapped in a conditional), do you know? – Bergi May 24 '14 at 20:54
  • @Bergi You mean to avoid calling a null or undefined? – stackunderflow May 24 '14 at 21:07
  • 1
    @stackunderflow Bergi was refering to the case where it'd act as a default parameter value. However, I believe it is best to avoid it as it is slow, unclear and can create unexpected results if mutated. – Benjamin Gruenbaum May 24 '14 at 21:08

1 Answers1

5

You should not set data on the prototype. A lot of times people who come to JavaScript from classical languages attempt it to emulate classical inheritance, but the assymetric nature of the prototype chain (setting is always local but getting climbs up the chain) means that it's impractical. For more information about prototypical inheritance, click here.

The prototype is for sharing functionality across instances. Put functions there instead. For sharing data, see this answer.

That article putting gender on the prototype is mistaken. This is why in ES6, maximally minimal classes set functions on the prototype, but not data members. See this article on why to avoid data on the prototype.

I've fixed the MDN article, nice catch.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • 2
    Wasn't me, but "*You should not set data on the prototype.*" lacks an explanation. I could imagine lots of use cases where it would be helpful. – Bergi May 24 '14 at 20:57
  • 1
    Well everywhere when you would want some "default data" for the case that a property was not assigned. Not uncommon in other prototype-base OOP languages. – Bergi May 24 '14 at 20:58
  • 2
    @Bergi Even if we ignore the fact that's slow since it forces a hidden classes deoptimization. You realize that implies changing the default on the prototype by mistake (say, you obtained a direct reference to it) changes the value on _every instance_, how many people do you think that could bite? Not to mention, I'm not sure all developers would realize the asymmetry (this is why we have the infamous for..in bugs) – Benjamin Gruenbaum May 24 '14 at 21:01
  • I gave you 1+ for the answer, and will mark it as the accepted answer, however your answer is extremely compact and very technical that newbees (me) will not digest it easily, like "but the assymetric nature of the prototype chain (setting is always local but getting climbs up the chain) " .. thanx – stackunderflow May 25 '14 at 09:10
  • 1
    @stackunderflow Ah, I did not want to rewrite answers already written in Stack Overflow again, I'll add references. Sorry. – Benjamin Gruenbaum May 25 '14 at 09:11