1

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?

Paritosh
  • 2,303
  • 2
  • 18
  • 24
  • Are you wondering how `sayMyName()` has access to the `Customer` name? – pimvdb Nov 14 '12 at 12:36
  • @pimvdb : No, I understood that part as in javascript if any property is not found in the object , it went up to the chain until it found one or undefined. My question is related to creation of myCustomer object as objects will be created on the basis of the Person's prototype. so how any public member of Customer got created ? am I making myself clear? – Paritosh Nov 14 '12 at 12:44

4 Answers4

1

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.

Community
  • 1
  • 1
Kos
  • 70,399
  • 25
  • 169
  • 233
  • (Now that I think of it, this looks more like an oversized comment than an answer. I'll leave it though) – Kos Nov 14 '12 at 12:38
  • `Object.create` will never be able to replace the power of constructor functions. – Bergi Nov 14 '12 at 12:48
  • @Kos :Thanks for reply, I know that javascript does not have class concept ,Everything got prototype from some object.I am using just sayin function as class. That is my question actually if X class/function have two property p1 and p2 and Y inherits it by pointing it prototype to X class/function. so if new object get created internal prototype will point to X class not Y class . Am I corret here? – Paritosh Nov 14 '12 at 12:49
  • @paritosh `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. – Kos Nov 14 '12 at 13:14
  • @paritosh The syntax `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()`"*. – Kos Nov 14 '12 at 13:15
  • @Bergi "the power of constructor functions" doesn't really sound technical; the discussion I've linked and articles mentioned there pretty much cover all there's to this debate IMHO. – Kos Nov 14 '12 at 13:16
  • @Kos : Nice explanation thanks that what I was looking for...although it will take a while to understand this concept :P – Paritosh Nov 14 '12 at 13:28
  • @Kos: Technically is was refering to the closure a constructor call creates. To cite [Felix Kling](http://stackoverflow.com/a/6613332/1048572): "*It [`Object.create`] is not a replacement for `new`. It is more an addition to make creating single objects which should inherit from another object simpler.*" I'd recommend to avoid it when mimicking classical inheritance. – Bergi Nov 14 '12 at 14:32
  • @Kos: Of a construcor. Inside you can create local variables and privileged functions. Also, you can just use the constructor function to initialize your objects (not creating any closures). – Bergi Nov 14 '12 at 18:24
  • @Bergi Privileged functions [as defined by Crockford in 2001](http://javascript.crockford.com/private.html)? They seem useful but using the closure requires you to create a separate function for every instance you create with `new`. Hence for private vars I prefer the ol' good Python approach - prefix the names with `_` and that's it. – Kos Nov 15 '12 at 08:43
  • @Bergi Also note that Crockford has been [recommending Object.create](http://javascript.crockford.com/prototypal.html) since 2006. Personally I think of this as mostly cosmetic difference since you can end up with the same objects no matter which syntax you use; I prefer `Object.create` because it makes the prototype chain explicit and doesn't try to mimic classical mechanisms just for the sake of it. – Kos Nov 15 '12 at 08:44
1

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.

pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • Just one more question : when we call new Customer () , it basically creates new object and sets it __proto__ property. so in this case where __proto__ is referring to or Person.Prototype or Customer .prototype? – Paritosh Nov 14 '12 at 12:58
  • @paritosh: The `__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. – pimvdb Nov 14 '12 at 13:00
0

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
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

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.

Brian Henry
  • 3,161
  • 1
  • 16
  • 17