Jared Meyering
Jared Meyering

Reputation: 1321

Prototypes and property inheritence in JavaScript

I am struggling accessing a property that is set on a child object and accessing it via method on its prototype.

var Parent = function () {
    this.getColor = function () {
        return this.color;
    };
};

var Child = function () {
    this.color = red;
};

Child.prototype = new Parent;

var Test = new Child();

console.log(Test.getColor());
=> undefined

Any and all assistance is appreciated.

Upvotes: 2

Views: 70

Answers (1)

maček
maček

Reputation: 77778

Here's how I'd do it

function Parent(color) {

  function getColor() {
    return color;
  }

  // export public functions
  this.getColor = getColor;
}

Now for the Child

function Child(color) {
  Parent.call(this, color);
}

Child.prototype = Object.create(Parent.prototype, {
  constructor: {value: Child}
});

Let's see it work

var c = new Child("red");
c.getColor(); // "red";

Explanation:

The important bits of the Child constructor

  1. Make sure to call the Parent constructor with the context of the Child instance (this)

    Parent.call(this, color);
    
  2. Setup the Child.prototype based off of the Parent.prototype

    Child.prototype = Object.create(Parent.prototype, {
      constructor: {value: Child}
    });
    

    You can see the node.js implementation of util.inherits uses a similar method.

    This somewhat complicated line does two things for you. 1) It avoids invoking the parent constructor unnecessarily, 2) It sets the constructor property properly.

    var c = new Child("red");
    c instanceof Child;  // true
    c instanceof Parent; // true
    c.constructor.name;  // "Child"
    

    But using your code, you would see

    var c = new Child("red");
    c instanceof Child;  // true
    c instanceof Parent; // true
    c.constructor.name;  // "Parent"
    

    This may or may not be a concern for you, but depending on how you want to use your parent/child objects, it may be hard to programmatically differentiate which objects are from the Parent constructor and which ones are from the Child constructor.


Ok, let's see another way to do it by assigning the color property on the object itself

function Parent(color) {
  this.color = color;
}

We'll add the getColor method directly to the Parent.prototype

Parent.prototype.getColor = function getColor() {
  return this.color;
};

The Child constructor will stay the same. Keep in mind we'll use the same inheritance pattern we used above

function Child(color) {
  Parent.call(this, color);
}

Child.prototype = Object.create(Parent.prototype, {
  constructor: {value: Child}
});

Lastly, let's get the color using our getColor method

var c = new Child("red");
c.getColor(); // "red"

Or you could access the property on the object directly

c.color; // "red"

Upvotes: 3

Related Questions