2

There is the most popular JavaScript method for inheritance:

function extend(Child, Parent) {
    var F = function() { }
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype;
}

I'm learning JS now, but I have a lot of Java experience and this inheritance model seems some diffucult for me. Why I can't do the following thing:

function extend(Child, Parent) {
    Child.prototype = Parent.prototype; 
    Child.prototype.constructor = Child;
}

I think I don't know/understand some things, but F object is useless in my opinion. Please, clarify the situation. Thanks.

malcoauri
  • 11,904
  • 28
  • 82
  • 137
  • 1
    In your second example, `Child.prototype === Parent.prototype` which would mean that any changes to `Child.prototype` would also change `Parent.prototype` because they'd be the same reference to the same object. – zzzzBov Oct 02 '13 at 18:54
  • It's best to avoid trying to think about JavaScript inheritance in terms of Java inheritance. The two architectures are **very** different. – Pointy Oct 02 '13 at 18:56
  • For modern browsers you can use Object.create to set inheritance. I've tried to describe prototype, inheritance, overriding and calling super in this answer: http://stackoverflow.com/a/16063711/1641941 It may be useful to understand what `this` refers to as well: http://stackoverflow.com/a/19068438/1641941 – HMR Oct 03 '13 at 04:15

3 Answers3

5
 Child.prototype = Parent.prototype; 

Now Child.prototype and Parent.prototype are the same object.

Adding methods to Child.prototype will add them to Parent.prototype, which is not how classic OOP inheritance works.

user229044
  • 232,980
  • 40
  • 330
  • 338
2

The most important thing to realize is that JavaScript does not have classical inheritance built in natively. It is not like Java so you'll want to throw all your Java inheritance ideas right out the window if you want to work with JavaScript's prototypes.

The idea of a prototype is that you have a single object connected to a constructor function. That's your prototype object. You use the constructor function to generate new objects that will all have access to the methods contained in the constructor's prototype. The trick is that if you ever modify the prototype attached to the constructor, the method you changed will now be changed for all child objects created by the constructor. It works like this:

function Cat(name) {
    this.name = name;
}

Cat.prototype = {
  furColor: function () {
    return 'gray';
  }
};

var kitty1 = new Cat('Bob');
//=> {name: 'Bob'}

kitty1.furColor();
//=> 'gray'

Cat.prototype.furColor = function () {
  return 'white';
}

var kitty2 = new Cat('Sally');
//=> {name: 'Sally'}

kitty2.furColor();
//=> 'white'

kitty1.furColor();
//=> 'white'

So if you want to build classical inheritance off of this model you can, but just remember, this is what you get with prototypes in JavaScript.

There's a pretty popular classical inheritance plugin that gives you some nice OO JavaScript called klass you might want to try instead of rolling your own.

rescuecreative
  • 3,607
  • 3
  • 18
  • 28
  • Thank you. Please, some other thing - I know about adding methods of class through prototype, but is it possible to add methods of class in "constructor" function? What way is better? – malcoauri Oct 02 '13 at 19:12
  • 1
    Add through prototype. From the horse's mouth: "I now see my early attempts to support the classical model in JavaScript as a mistake." http://www.crockford.com/javascript/inheritance.html I couldn't agree more. Why fake it if it's not there? If you want to learn Japanese, you learn Japanese, you wouldn't go and conceive your own Japanese dialect and hope Japanese people will learn it in order to understand you. – itmitica Oct 02 '13 at 19:55
  • You can assign a function to the object within the constructor however, that function will be considered an "owned property" of the object. When it is in the prototype, it is not considered an actual member property of generated objects. Pros and cons. It's all about what you are trying to accomplish. But in the same way that you shouldn't try to write Java with a Haskell style, you may not really want to write JS with a Java style. – rescuecreative Oct 02 '13 at 19:59
0

I believe that a javascript prototype is an actual instance of an object, and if you do something like:

Child.prototype = Parent.prototype; 
Child.prototype.constructor = Child;

you'll also be changing the Parent's prototype too, because they're the same instance of an object.