0

I'm trying to do a simple practice in Javascript Inheritance but I cannot understand what is going on with this code:

function person() {
    this.firstName = 'asdf';
    this.lastName = 'asdfasdf';
    this.showName = function () {
        console.log(this.firstName);
    }
}

function employee() {
    person.call(this);
}
employee.prototype = person.prototype;
employee.prototype.showName = function showName() {
    console.log = "I am an employee";
};

var p = new person();
p.showName();
var e = new employee();
e.showName();

In this code the e.showName is still calling its parent method, despite the fact that I was trying to override the method. What did I do wrong?

Fábio Duque Silva
  • 2,146
  • 1
  • 18
  • 16
Pouyan
  • 2,849
  • 8
  • 33
  • 39
  • Take a look here: http://cssdeck.com/labs/4ctbg7ey . As I understood you should override methods not in prototype but in target class itself – Mark Zucchini Nov 07 '14 at 17:51
  • 1
    I've edited your tags: you're not talking about "PrototypeJS" but about "prototype" (standard JS approach to inheritance) – Matías Fidemraizer Nov 07 '14 at 17:56
  • Maybe the following answer can be of use to you: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Nov 08 '14 at 03:07

3 Answers3

1

This is because of prototype chain. JavaScript runtime will look for the nearest definition of requested property.

Since you're defining showName in person during the constructor call, you're defining a showName in the object rather than in the prototype. Runtime will look for the nearest property called showName and it'll find this.showName before prototype.showName.

Just try to define showName in person in the prototype instead of in the object itself:

function person() {
  ...
}

person.prototype = { 
      showName: function() {
          ...
      }
}

...and you'll get the expected result!

In other words...

Let's say you've the following JavaScript constructor function:

var A = function() {
    this.doX = function() {};
};

A.prototype = {
   doX: function() { }
};

What function will be called if I create an instance of A?

var instance = new A();
instance.doX(); // ?????

The doX() added during the construction time will be the one called by the runtime instead of the one defined in the prototype.

In fact, the doX() defined in the A constructor is equivalent to just doing the following declaration:

var instance = new A();
instance.doX = function() {};

The this keyword inside the A constructor is a reference of the instantiated object, thus it's the same declaring it inside or outside the constructor - actually there's a single difference: if you declare outside the constructor, not all A instances will own the whole property... -.

At the end of the day, properties declared in the object hide ones declared in the prototype, and this is what happened in your code, because employee calls the person constructor with the this reference of employee, meaning that showName in person will hide the one declared in the employee prototype.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
0
function Person() {
  this.name = 'Jack';
  this.age = 72;  

  this.showName = function() {
    return 'Person: ' + this.name;
  }
}

function Student() {
  Person.call(this);  

  this.showName = function() {
    return 'Student: ' + this.name;  
  }
}

var p = new Person();
alert(p.showName()); // Shows 'Person: Jack'
var s = new Student();
alert(s.showName()); // Shows 'Student: Jack'
Mark Zucchini
  • 925
  • 6
  • 11
  • An answer stating showname would be better on Person.prototype and setting Student.prototype equal to Person.prototype is not correctly inheriting may have been better. You now solved the problem by ditching the prototype completely – HMR Nov 08 '14 at 03:10
0

Prototype object is the parent object of the person

so you are overwriting the prototype showName() with the person showName() so the out put is the person firstname is printing in the console.

Mateen
  • 1,631
  • 1
  • 23
  • 27