How to think about it: In Javascript and similar languages, each object has a prototype, which in itself is also an object. If you try to access a method or property (since functions are first-class in javascript, then the difference between the method and the property is misleading) of the object, and if the interpreter cannot find on the object itself, it will look on the prototype. Since the prototype is also an object, it also has its own prototype (prototype of the prototype of the object). Thus, there is a chain of prototypes, one for each level of inheritance, which traces the entire path to the base class object, and at that moment, if it has not yet found the property that you tried to get to the interpreter, the undefined property throws an error.
How to implement it: There are many ways to make inheritance, this is the one I use, which is not the best, but the easiest to understand:
//A constructor var A= function() {}; A.prototype.doSomething= function() { }; A.prototype.doSomethingElse= function() { }; //B constructor var B= function () { A.apply(this, arguments); //calls A constructor on this instance of B }; B.prototype= new A(); //this makes B "extend" A. Basically it sets B prototype to be an instance of ABprototype.doSomething= function() { A.doSomething.apply(this, arguments); //calling "super" }; B.prototype.doSomethingElse= function() { A.doSomethingElse.apply(this, arguments); //calling "super" }; //C constructor var C= function () { A.apply(this, arguments); }; C.prototype= new A(); C.prototype.doSomething= function() { A.doSomething.apply(this, arguments); //calling "super" }; C.prototype.doSomethingElse= function() { A.doSomethingElse.apply(this, arguments); //calling "super" };
So if you say that C does not have a doSomethingElse method, and you do something like:
c= new C(); c.doSomethingElse();
It will call the A.doSomethingElse method in instance c.
A small explanation of the .apply function: Functions in javascript "extend" an object, so they themselves are an object. In fact, you can really do this:
var myFunc= new Function("alert('myFunc');"); myFunc();
Since functions are objects, they also have their own properties and methods. "apply" is one of them.
When you say this:
In fact, you create a function and store it in A, then you put the method inside the prototype (remember that functions are objects, so they have prototypes). When you do this:
var a= new A(arg1,arg2,arg3...);
You make an instance of A, the “new” statement is a special kind of statement that basically does this:
a= A.apply(a, [arg1,arg2,arg3,...]); a.prototype= A.prototype;
Here is an example of the Function.apply method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply?redirectlocale=en-US&redirectslug = JavaScript% 2FReference% 2FGlobal_Objects% 2FFunction% 2Fapply
And here is the explanation of the "arguments" array that is passed to it: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments
When you say this:
C.prototype.doSomething= function() { A.doSomething.apply(this, arguments); };
Please note that A.doSomething in this case is a kind of analogue of a static function in Java, you do not call the instance method A, but in fact the method is present in the constructor of function A (the method is actually on A.prototype, but since the functions are objects, the interpreter will search for them on the prototype by itself).
You can do all this because the constructor is a function, and functions are objects, and objects have prototypes and prototypes - objects and objects can have functions within themselves. Crazy huh? But if you stop thinking about the prototype chain explained earlier, it's not that difficult. Just re-read this sentence a couple of times.
Why is all this stupidity? You are probably a little confused right now, and I urge you to look for more examples online. But it is easy to say that it is complex and overly complex, but it is kind (in javascript), but it is also very powerful. You can change the behavior of objects at runtime:
If you execute this small bit of code at any given time
A.prototype.doSomething= function() { A.doSomethingElse.(apply(this, arguments)); }
you actually change the behavior of all instances of A and any other class that inherits from it (all instances of B and C also change). In this case, your A.doSomething will behave exactly like A.doSomethingElse. Think of Java reflections without any crazy code.
In fact, you can change the behavior of inline Javascript classes such as String or Array: If you run this code somewhere in your program:
String.prototype.alert= function() { alert(this); }
Now you can do the following: "Text" .alert (); A popup will appear with text inside it. But do not modify the built-in classes, this is bad practice.
This is just one of the many benefits of using an object-oriented prototype object orientation. There are many others.
What about private methods? They do not exist in javascript, but you can create functions that are visible to only one function through closure. If you need to do private methods, I recommend that you read about closing.