user3412869 user3412869 - 2 months ago 14
Javascript Question

JavaScript OOP Prototype Outside of Constructor?

I was reading the guide to OOP JS and came across this snippet:

function Person(gender) {
this.gender = gender;

Person.prototype.gender = '';

Person.prototype.sayHello = function () {
alert ('hello');

var person1 = new Person('Male');
var person2 = new Person('Female');

// call the Person sayHello method.
person1.sayHello(); // hello

I don't understand, if (gender) is already defined as this.gender; why do we need to put the Person.prototype.gender = ''; line? I understand it for functions outside of the constructor, but it seems like that line is repeating the this.gender; line. I understand it is creating gender as a property of the Person() object, but doesn't that just repeat the this.gender?

I would appreciate any explanation, I'm new to OOP JS. Thanks!


By adding Person.prototype.gender = ''; the Person has a "default" gender persay. It is more like defining a gender for the Person if no gender is specified at instantiation. Keep in mind, setting this.gender = gender when gender is undefined still counts as specifying a value.

When it becomes obvious is if you try to delete the gender property from your persons. If Person.prototype.gender = ''; is omitted, then the following situations can occur:

var person1 = new Person('Male');

// check gender
person1.gender === 'Male'; // true

// remove gender property from person1
delete person1.gender;

person1.gender === undefined; // true

Because person1 does not have gender anymore, it cannot reference it in this Person instance, so it will look up its prototype chain at the Person constructor. And it won't find it there because in the constructor this.gender = gender; is a instance property. The lookup process continues up the prototype chain until it finds the property.

Now consider if we have the following:

function Person(gender) {
  this.gender = gender;

Person.prototype.gender = 'Asexual';

var person1 = new Person('Male');
var person2 = new Person('Female');
var person3 = new Person();

// check genders, looking at instance property
person1.gender === 'Male'; //true
person2.gender === 'Female'; //true
person3.gender === undefined; //true

// remove their genders
delete person1.gender;
delete person2.gender;
delete person3.gender;

// check genders again, now it's looking up the prototype chain 
person1.gender === 'Asexual'; //true
person2.gender === 'Asexual'; //true
person3.gender === 'Asexual'; //true