JS Implementation "extends" as functionality (REALLY simple inheritance)

Say I have a class in JS with prototype functions ...

function Foo() { this.stuff = 7; this.otherStuff = 5; } Foo.prototype.doSomething = function() { }; Foo.prototype.doSomethingElse = function() { }; 

Now say that I want to โ€œextendโ€ this class by subclassing it. In Java, it will look like ...

 public class Bar extends Foo {} 

Now I know that in JS there really is no class concept, everything can be changed, and all this really just comes down to crap dictionaries, but, nevertheless, I should be able to copy the prototype of one class and add it to the prototype of the other, right?

What will be the code for something similar in vanilla JS?

+4
source share
5 answers

Something like that...

 function Bar(){ // your code } Bar.prototype = new Foo(); // Bar extends Foo 
+3
source

One way as shown below

 function Foo() { this.stuff = 7; this.otherStuff = 5; } Foo.prototype.doSomething = function() { alert("some"); }; Foo.prototype.doSomethingElse = function() { }; function Bar() { Foo.call(this); // this line } Bar.prototype = Object.create(Foo.prototype); var b = new Bar(); b.doSomething(); 
+3
source

The accepted answer will definitely do the trick. And this โ€œshortโ€ explanation turned into a leap, but hopefully it is useful.

There is one thing you should know about with the accepted answer. When you basically โ€œinheritโ€ by doing Bar.prototype = new Foo() , you call the constructor. So, if you have code in your constructor that will not be used as a launch pad for another "class", you will come across strange effects. Take for example:

 var Person = function (firstName, lastName) { .... }; var Student = function (firstName, lastName, grade) { .... }; 

Let's say Student is an extension of Person . How are you going to create a prototype on Student ? Probably not like Student.prototype = new Person("John", "Doe");

Another processing method, which is a bit more complicated, but can be wrapped inside another function, is as follows:

 var extend = function (child, parent) { var f = function () {}; f.prototype = parent.prototype; child.prototype = new f(); child.prototype.constructor = parent; } var Person = function (firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } Person.prototype.getName = function () { return this.firstName + " " + this.lastName; } Person.prototype.setAge = function (age) { this.age = age; } var Student = function (firstName, lastName, grade) { Person.call(this, firstName, lastName); this.grade = grade; }; extend(Student, Person); //<< do this before adding stuff to the prototype Student.prototype.getName = function () { var name = Person.prototype.getName.apply(this); return name + ", Grade " + this.grade; } Student.prototype.tooOldToBeAStudent = function () { if(this.age > 18) { return true; } } var p = new Person("Joe", "DiMaggio"); var s = new Student("Jack", "Sparrow", 12); console.log(p.getName(), s.getName()); //consoles "Joe DiMaggio" "Jack Sparrow, Grade 12" console.log(s instanceof Person); //true - even with the weird looking inheritance, Student is still an instance of Person. s.setAge(30); console.log(s.age); //30, just like what you'd expect with a Person object. console.log(s.tooOldToBeAStudent); //true - as mentioned previously, 'age' is set via its inherited method. 

This gives you not only the functionality of Person, but also allows you to build . It looks like what you are actually doing with inheritance.

How it works? Great question. First, objects are assigned around [mostly] by reference. The prototype is an object. So, in the extend function, I create an empty function that will serve as a surrogate for child . This copies the parent prototype for itself, and then creates a new instance of the child prototype itself. Thus, the parent constructor is not called, but the original prototype is still in use. To make sure instanceof still works, child.prototype.constructor set to parent - it effectively informs javascript that the thing the child came from is a parent, not a surrogate.

In addition, when overriding methods, you can use the "class" that you inherit from the prototype method, and apply or call it with this -, which starts the method with the scope of the current object, and you can pass any arguments that you feel, but they are accepted by your chosen function. For example, Person.prototype.getName.apply(this); runs Person getName in the context of the current instance of the student. Suppose we wanted to override setAge to just console.log to print the age.

 Student.prototype.setAge = function () { Person.prototype.setAge.apply(this, arguments); console.log(this.age); } 

This is where the Person setAge with the arguments that were passed to Student setAge . Thus, it basically allows you to transfer material without having to know about the details of the original arguments of the method.

+2
source

The solution provided by mohkhan is out of date. A new way of inheritance is as follows:

 function Bar() { Foo.call(this, /* additional arguments if required */); } Bar.prototype = Object.create(Foo.prototype); Bar.prototype.constructor = Bar; // don't forget to do this 

If you want your code to look more classic, take a look at the augment method. Using the add-on, you can write the above code as:

 var Bar = Foo.augment(function (base) { this.constructor = function () { base.constructor.call(this, /* additional arguments if required */); }; }); 

The augment method itself represents just seven lines of code:

 Function.prototype.augment = function (body) { var base = this.prototype; var prototype = Object.create(base); body.apply(prototype, Array.prototype.slice.call(arguments, 1).concat(base)); if (!Object.hasOwnProperty.call(prototype, "constructor")) return prototype; var constructor = prototype.constructor; constructor.prototype = prototype; return constructor; }; 

Seriously, use the new way. It is better. Here's why: JavaScript Inheritance: Calling Object.create when setting up a prototype

+2
source

class extension template in javascript is different from java

 var Person = Class.extend({ init: function(isDancing){ this.dancing = isDancing; }, dance: function(){ return this.dancing; } }); var Ninja = Person.extend({ init: function(){ this._super( false ); }, dance: function(){ // Call the inherited version of dance() return this._super(); }, swingSword: function(){ return true; } }); var p = new Person(true); p.dance(); // => true var n = new Ninja(); n.dance(); // => false n.swingSword(); // => true // Should all be true p instanceof Person && p instanceof Class && n instanceof Ninja && n instanceof Person && n instanceof Class 
-3
source

Source: https://habr.com/ru/post/1491775/


All Articles