0

I want the man object inherits from the person object. I could have done it using the new operator, but it should work with Object.create. But why it is not working? The console.log says undefined instead of the expected hello.

function person() {
    this.say="hello";
}

function man() {
    this.name="John Miler";
}

man.prototype = Object.create(person);

var Johnny = new man();

console.log(Johnny.say);  

4
  • 2
    The 1st parameter of Object.create should be prototype, not constructor (as you supplied). Pass person.prototype instead of person Commented Feb 7, 2016 at 8:34
  • However the 1st parameter is used to copy methods rather than properties. In order to populate properties, you have to supply the 2nd parameter. Commented Feb 7, 2016 at 8:42
  • @hindmost The first parameter can be any object, even {} or also null. All the properties in that object will be inherited, no matter which of the type they are. Commented Feb 7, 2016 at 8:47
  • @Teemu Ok. Let me rephrase it: It is supposed to be a prototype of a newly-created object. It can be almost anything. However in the case of passing constructor, it will be treated in a wrong way (not what the OP expects). Commented Feb 7, 2016 at 8:52

3 Answers 3

3

Your problem is two-fold.

Problem 1:

Object.create should be passed the prototype, not the constructor. In this case, you should use Object.create(person.prototype);, not Object.create(person);


Problem 2:

The say property is added when the constructor is called, and you never call the parent constructor from the child constructor.

There are a couple ways to solve this, depending on your desired behavior.

Option 1, call parent constructor.

person.call(this);

Sample:

function person() {
    this.say="hello";
}

function man() {
    person.call(this);
    this.name="John Miler";
}

man.prototype = Object.create(person.prototype);

var Johnny = new man();

console.log(Johnny.say);  

Option 2, make it a static property.

person.prototype.say = "hello";

Sample:

function person() {
}
person.prototype.say = "hello";

function man() {
    this.name="John Miler";
}

man.prototype = Object.create(person.prototype);

var Johnny = new man();

console.log(Johnny.say);  

Sign up to request clarification or add additional context in comments.

1 Comment

@Zephyrs For proper prototypical inheritance (ie. the instanceof keyword), you would still need to use Object.create in addition to .call. If you don't want the property to change, using a static property is the correct solution. However, if you want it to be dynamic, using .call is the correct solution.
0

If what you try to achieve is for a man object to inherit a person object, try this:

// superclass
function Person() {
  this.say = "hello";
}

// superclass method
Person.prototype.doStuff = function() {
  console.info('Stuff done.');
};

// subclass
function Man() {
  Person.call(this); // call super constructor.
  this.name="John Miler";
}

// subclass extends superclass
Man.prototype = Object.create(Person.prototype);
Man.prototype.constructor = Man;


var Johnny = new Man();

console.log(Johnny.say); // hello

Comments

0

Object.create should be passed the prototype not the constructor.

function person() {
 this.say="hello";
}

function man() {
 this.name="John Miler";
}

man.prototype = Object.create(new person());

var Johnny = new man();

console.log(Johnny.say);

2 Comments

You say that the prototype should be passed, but in the code you're passing an instance???
By prototype I mean the base object, not the prototype property

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.