Here I am trying to understand few concepts of inheritance in javascript.I have created person class and trying to inherit it in Customer class.
var Person = function(name) {
this.name = name;
};
Person.prototype.getName = function() {
return this.name;
};
Person.prototype.sayMyName = function() {
alert('Hello, my name is ' + this.getName());
};
var Customer = function(name) {
this.name = name;
};
Customer.prototype = new Person();
var myCustomer = new Customer('Dream Inc.');
myCustomer.sayMyName();
Every time a new object gets created ,javascript engine basically calls prototype's constructor. here I am trying to understand few things:
if Customer prototype is referring to Person object.So creation of new Customer object should contain only Person property/Method not the Customer property/Method.How Customer property get attached to the new Customer object (myCustomer)?
Am I missing some javascript concept here?
4 Answers 4
Here I am trying to understand few concepts of inheritance in javascript.I have created person class and trying to inherit it in Customer class.
Well then you sure have lost your way quickly. There are no classes in prototypal inheritance.
That's the whole point! :-)
Using .prototype and new Function() syntax isn't a very explicit way to leverage prototypal inheritance.
Consider using Object.create instead of new - this way allows you to directly say which object is supposed to be which's prototype. It's more straightforward and you're likely to grasp the idea of prototypes faster this way.
Also, if you want to have longer prototype chains, then this method will certainly be more comfortable to use.
11 Comments
Object.create will never be able to replace the power of constructor functions.myCustomer's prototype (accessible via proto) is Customer.prototype, which happens to be an object created via new Person() that has Person.prototype as its prototype. So the prototype chain for myCustomer is new Person() (a single Person instance) -> Person.prototype -> Object. The property lookup travels across this chain.Customer.prototype is a bit misleading; read it as "Customer.prototype is an object which will serve as prototype for objects created via new Customer()".You defined Person and Customer, and then set Customer's prototype to a Person instance. So, your chain looks like this:
myCustomer (a Customer instance)
Customer prototype (a Person instance)
Person prototype (a plain object)
Indeed, myCustomer is a Customer instance as it has Customer's prototype in its chain. It's not the same thing as a direct Person instance. The latter would not have Customer's prototype in the chain.
2 Comments
__proto__ of new constructor() is equal to constructor.prototype. So in this case it is Customer.prototype. This itself is a Person instance and has Person.prototype as __proto__ one level down in the chain.if Customer prototype is referring to Person object and so on creation new Customer object should contain only Person property/Method not Customer property/Method.
Yes. Your newly created Customer object inherits from the Person instance in Customer.prototype. As you have neither added properties to that prototype object, nor create properties to your instance in the Customer constructor, your customer contains only the person's properties.
How Customer property get attached to the new Customer object (myCustomer)?
Do it in the constructor function:
function Customer (){
this.customer_property = someValue;
}
This code is executed each time an instance is created via new. If you don't need that, you can just add the methods etc. to the Customer.prototype object.
Also have a look at What is the reason [not] to use the 'new' keyword here? - you should not instantiate a Person for the prototype object - why should all customers inherit its name etc? Use
function Customer(name) {
Person.call(this, name); // apply Person constructor on this instance
// for creating own properties (and privileged methodes)
// custom Customer code
}
Customer.prototype = Object.create(Person.prototype);
Customer.prototype.someMethod = ... // Customer-specific prototype things
Comments
I think the confusion lies in saying "javascript engine basically calls prototype's constructor". For a new instance of your Customer, Javascript will create a new object, set the prototype to the Person object you've designated, then call your Customer constructor function to customize the object (this is the illusion of "class" in JS). There's no re-calling of the prototype constructor function. So, your fields/methods for Customer are set, in your Customer constructor.
When a customer object has a method/field referenced after construction, the javascript engine will try to find it in the fields/methods that were set via your constructor (or in code manipulating the object downstream of the constructor call). If it can't, it will look to the prototype object attached to find the method/field. In this way are both the Customer fields/methods available and the "superclass" fields/methods.
sayMyName()has access to theCustomername?