2

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.

7
  • That works just fine -> jsfiddle.net/eYnPq, as long as red is defined. Commented Jul 20, 2014 at 17:48
  • 1
    @adeneo your version has quotes around red :) Commented Jul 20, 2014 at 17:48
  • 2
    @Pointy - I assumed it was a variable, and it's probably undefined. If it wasn't declared it would be an error. Commented Jul 20, 2014 at 17:49
  • 1
    Yes I think that's where the undefined in the OP version is coming from; the assignment leaves this.color as undefined. Commented Jul 20, 2014 at 17:50
  • @Pointy - seems like the only possible way for that result, so the answer is that red is declared, but it has no value, hence undefined Commented Jul 20, 2014 at 17:50

1 Answer 1

3

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"
Sign up to request clarification or add additional context in comments.

5 Comments

No. The primary reason for this somewhat complicated line is to use Object.create for inheriting from the Parent's prototype without invoking the constructor. The second parameter to Object.create could be omitted and replaced by a simple property assignment.
@Bergi, "primary reasons" aside, it objectively does two things, and thank you for calling out one I didn't mention. I've edited my post to leave my opinions out of the matter :)
You know that you didn't really answer the question, right? It doesn't matter if there is a better way of setting up inheritance - if the OP doesn't have a grasp of what the code he/she currently has is doing and why it's not working, just throwing other patterns at him/her is not really going to help.
I must admit that Stephen is right (though that "triviality" has been settled in the comments already), but have a +1 for the correct inheritance nonetheless :-)
Fair enough, gentlemen. I've added an alternative solution that shows how to set the value as a property on the object itself. Thanks for the constructive feedback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.