The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object. getPrototypeOf and Object.
So, the core idea of Prototypal Inheritance is that an object can point to another object and inherit all its properties. The main purpose is to allow multiple instances of an object to share common properties, hence, the Singleton Pattern.
In JavaScript, an object can inherit properties of another object. The object from where the properties are inherited is called the prototype. In short, objects can inherit properties from other objects — the prototypes.
Both classical and prototypal inheritance are object-oriented programming paradigms. Objects in object-oriented programming are abstractions that encapsulate the properties of an entity.
To add to Norbert Hartl's answer, SuperCar.prototype.constructor isn't needed, but some people use it as a convenient way of getting the constructing function of an object (SuperCar objects in this case).
Just from the first example, Car.call(this, name) is in the SuperCar constructor function because when you do this:
var mySuperCar = new SuperCar("SuperCar");
This is what JavaScript does:
Notice how JavaScript didn't call Car for you. Prototypes being as they are, any property or method that you don't set yourself for SuperCar will be looked up in Car. Sometimes this is good, e.g. SuperCar doesn't have a Drive method, but it can share Car's one, so all SuperCars will use the same Drive method. Other times you don't want sharing, like each SuperCar having it's own Name. So how does one go about setting each SuperCar's name to it's own thing? You could set this.Name inside the SuperCar constructor function:
function SuperCar(name){
this.Name = name;
}
This works, but wait a second. Didn't we do exactly the same thing in the Car constructor? Don't want to repeat ourselves. Since Car sets the name already, let's just call it.
function SuperCar(name){
this = Car(name);
}
Whoops, you never want to change the special this
object reference. Remember the 4 steps? Hang onto that object that JavaScript gave you, because it's the only way to keep the precious internal prototype link between your SuperCar object and Car. So how do we set Name, without repeating ourselves and without throwing away our fresh SuperCar object JavaScript spent so much special effort to prepare for us?
Two things. One: the meaning of this
is flexible. Two: Car is a function. It's possible to call Car, not with a pristine, fresh instantiated object, but instead with, say, a SuperCar object. That gives us the final solution, which is part of the first example in your question:
function SuperCar(name){
Car.call(this, name);
}
As a function, Car is allowed to be invoked with the function's call method, which changes the meaning of this
within Car to the SuperCar instance we're building up. Presto! Now each SuperCar gets it's own Name property.
To wrap up, Car.call(this, name)
in the SuperCar constructor gives each new SuperCar object it's own unique Name property, but without duplicating the code that's already in Car.
Prototypes aren't scary once you understand them, but they're not much like the classic class/inheritence OOP model at all. I wrote an article about the prototypes concept in JavaScript. It's written for a game engine that uses JavaScript, but it's the same JavaScript engine used by Firefox, so it should all be relevant. Hope this helps.
The two blocks differ in a way that in the first example Drive()
will only exist once while at the second approach Drive()
will exist per instance (Every time you do new Car()
the function drive()
will be created again). Or different said the first uses the prototype to store the function and the second the constructor. The lookup for functions is constructor and then prototype. So for your lookup of Drive()
it finds it regardless if it is in the constructor or in the prototype. Using the prototype is more efficient because usually you need a function only once per type.
The new
call in javascript automatically sets the constructor in the prototype. If you are overwriting the prototype so you have to set the constructor manually.
Inheritance in javascript has nothing like super
. So if you have a subclass the only chance to call the super constructor is by its name.
Norbert, you should note that your first example is pretty much what Douglas Crockford calls pseudoclassical inheritance. Something things to note about this:
Lastly, I'd like to mention that I have several examples of TDD JavaScript Inheritance code that works here: TDD JavaScript Inheritance Code and Essay I'd love to get your feedback as I'm hoping to improve it and keep it open source. The goal is to help classical programmers get up to speed with JavaScript quickly and also supplement the study both Crockford and Zakas books.
I am not 100% sure, but I believe the difference is that the second example simply duplicates the contents of the Car class into the SuperCar object, while the first links the SuperCar prototype to the Car class, so that run-time changes to the Car class affect the SuperCar class as well.
function abc() {
}
Prototype methods and property created for function abc
abc.prototype.testProperty = 'Hi, I am prototype property';
abc.prototype.testMethod = function() {
alert('Hi i am prototype method')
}
Creating new instances for function abc
var objx = new abc();
console.log(objx.testProperty); // will display Hi, I am prototype property
objx.testMethod();// alert Hi i am prototype method
var objy = new abc();
console.log(objy.testProperty); //will display Hi, I am prototype property
objy.testProperty = Hi, I am over-ridden prototype property
console.log(objy.testProperty); //will display Hi, I am over-ridden prototype property
http://astutejs.blogspot.in/2015/10/javascript-prototype-is-easy.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With