Trying to understand JavaScript inheritance

I am very new to JavaScript and come from a C ++ / Java background, so I'm more used to the "classic" languages.

How will I implement the following in JavaScript since it has no classes !?

Suppose I have a base class A that defines some functions that the derived classes B and C must implement, for example (Java ish psuedo-code):

public class A { public void doSomething(); public void doSomethingElse(); }; public class B extends A { public void doSomething() { // does B sort of something }; public void doSomethingElse() { // does B sort of something else }; }; }; public class C extends A { public void doSomething() { // does C sort of something }; public void doSomethingElse() { // does C sort of something else }; }; }; 

Then I want to create B or C and work with it, knowing that it will have all the functions defined in A.

eg.

 A a = new B(); b.doSomething(); 

I don’t even know if this is how I should think when programming in JS? I read some Douglas Crockford web pages, but I'm still confused !!!.

+1
javascript inheritance
source share
3 answers
 function A() { }; A.prototype.doSomething = function() { console.log("hi") } A.prototype.doSomethingElse = function() {} function B() { A.apply(this,arguments) ) }; function C() { A.apply(this,arguments) ) }; B.prototype = Object.create(A.prototype); C.prototype = Object.create(A.prototype); var b = new B(); var c = new C(); b.doSomething(); c.doSomethingElse(); 

You can inherit from other objects by setting these objects in the prototype chain of the function.

Since you can override these basic functions, you can do it like this:

 B.prototype.doSomething = function() { console.log("goodbye"); } 

Objects of type b are then forgiven, not greeted, when you call doSomething, c will remain unchanged.

Here you can play with the experiment http://jsfiddle.net/Yp3UR/

There are good external resources in this.

In Stackoverflow you can see

  • What methods can be used to define a class in JavaScript and what are their tradeoffs? for a good overview of JS classes
  • How to and quot; create custom object in javascript? for a more general look at object creation in JS
+2
source share

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:

 //A constructor var A= function() {}; A.prototype.doSomething= function() { }; 

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.

+1
source share

You need to make a prototype chain between classes. B.proto should point to A, as well as C.proto. The prototype method consists of the __proto__ attribute. There used to be big disagreements about __proto__ , because not all JS modules implement it, although these days they do.

The implementation of __proto__ is still optional in the ES6 specification, but the standard will include Object.setPrototypeOf() for a chain of objects.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf

Here you can solve your question without using the new () operator. Check this question “How to properly create a custom object in javascript” to find out why using the new() operator to create objects should be discouraged.

 Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) { obj.__proto__ = proto; return obj; } function A() { var a = {}; a.doSomething = function() { console.log("A.doSomething()"); } return a; } function B() { var b = {}; Object.setPrototypeOf(b, A()); b.doSomethingElse = function() { console.log("B.doSomethingElse()"); } return b; } function C() { var c = {}; Object.setPrototypeOf(c, A()); c.doSomething = function() { this.__proto__.doSomething(); console.log("C.doSomething()"); } return c; } var a = A(); var b = B(); var c = C(); a.doSomething(); b.doSomething(); b.doSomethingElse(); c.doSomething(); 

Output:

 A.doSomething() A.doSomething() B.doSomethingElse() A.doSomething() C.doSomething() 
0
source share

All Articles