The user JonathanLonowski already answered your question about how to avoid to call the construction when setting up inheritanc. But I also read your question to be a general question about how inhertance works in JavaScript. So here is my attempt to explain this topic:
When it comes to inheritance, what you basically want to do is to enhance the prototype chain.
So, what it the prototype chain?
When you request a property of an object with i.e. obj.prop
, JavaScript first checks, if the object obj
has such a property. If not, it checks if the prototype of that object has such a property. If not, it checks if the prototype of the prototype has such a property and so on.
When you create a new object with a constructor function by writing obj = new B()
then the prototype chains look as follows:
obj -> B.prototype -> Object -> null
How inheritance works with prototype chains
If you want your B
objects to inherit from object of type A
, you want you prototype chain to look like this:
obj -> B.prototype -> A.prototype -> Object -> null
To achieve this you "break" the prototype chain after B.prototype
and insert instead the full prototype chain of A
. Or in other words, you want to set B.prototype
to point to A.prototype
.
You can do this, as you did before:
B.prototype = new A();
Now why does this work? The object created by new A()
has the following prototype chain:
objA -> B.prototype -> Object -> null
If you override B.prototype
with this object, the prototype chain of an object of type B
looks like this:
objB -> objA -> A.prototype -> Object -> null
And as you see, it works. By simply overriding B.prototype
you just lose some properties like the constructor
property. So if you try to get the constructor
of an object of type B
with objB.constructor
, it first looks in the object itself and doesn't find it, then looks in objA
and doesn't find it and then looks in A.prototype
and find A
, which is wrong. Although you don't need the constructor
property very often it can be considered good practice to set it again after overriding B.prototype
:
B.prototype = new A();
B.prototype.constructor = B;
Now, your way is just ONE way to achieve linking of the prototype chains. The solution by JonathanLonowski is another one and indeed a better one, since it doesn't call the function A
. It creates an empty object with the same prototype chain as an object of type A
:
(empty object) -> A.prototype -> Object -> null
Another solution would be to not override B.prototype
but modify it to simply point to A.prototype
instead of Object
. Not every browser supports this, but in some you can achieve this by setting the __proto__
property:
B.prototype.__proto__ = A.prototype;
This will result in the following prototype chain:
obj -> B.prototype -> A.prototype -> Object -> null
Please note, that I simplyfied it here and there, but I think this should give you an idea of how it works. The very basic thing to understand is prototyping. Now, technically, there is only one true prototype property, that every object has and that is the internal [[prototype]]
property. You can't access it directly in JavaScript, but you have .prototype
and .__proto__
to set it and manipulate it under certain conditions.