Trying a simple approach to OPP inheritance in Javascript (ES5)

Just for the sake of curiosity, I played with prototype inheritance and OOP inheritance in Javascript. Most results include emulating the concepts of "Class" and "extends" with functions, while others use prototypes and constructors.

I wrote this code:

function Warrior(weaponName) { var weapon = weaponName; this.getWeapon = function() { return weapon; }; this.setWeapon = function(value) { weapon = value; }; this.displayInfo = function() { return { "weapon": this.getWeapon(), }; }; } function Archer() { var accuracy = "86%"; this.parent = Archer.prototype; // Inheritance workaround this.getAccuracy = function() { return accuracy; }; this.setAccuracy = function(value) { accuracy = value; }; this.displayInfo = function() { var form = this.parent.displayInfo(); form.accuracy = this.getAccuracy(); return form; }; } Archer.prototype = new Warrior("bow"); var w = new Warrior("sword"); var a = new Archer(); console.log(w.displayInfo()); console.log(a.displayInfo()); 

I made it so that when displaying information from the Warrior class, it would show the object as

 { weapon: "sword" } 

And when the information from Archer is shown, the object:

 { weapon: "sword", accuracy: "86%" } 

A "subclass" takes information from a "superclass" and adds to it. The call to getWeapon () or setWeapon from Archer also works. The chain continues without problems, even when I add the third class of Kyudok, which extends Archer and has its own properties.

But compared to the more complex code that I found during the research, I believe that it can be a naive implementation (the Inheritance line), and I'm missing something (given that JS has a lot of subtlety).

This is a theoretical question, I do not use this code on any system.

+5
source share
2 answers

There are basically 3 types of inheritance in javascript, according to the Javascript Good Parts book: Pseudoclassical , Prototypal, and Functional .

The one you just posted will fall under Pseudoclassical inheritance, where you emulate class behavior using constructor functions.

I find the Functional template more useful and flexible, which allows you to protect your variables (make them private).

 var constructor = function (spec, my) { var that, other private instance variables; my = my || {}; //Add shared variables and functions to my that = a new object; //Add privileged methods to that return that; } 

Prototypal is that your objects are inherited directly from another useful object, which would look like they (useful objects) would be the prototype of your new object.

 Object.beget = function (o) { var F = function () {}; F.prototype = o; return new F(); }; var a = {} //Add shared variables to a var b = Object.beget(a); //Add new methods to b 

This is a lot of considerations for each of the templates, for example, Crockford says in his book "A functional template has a lot of flexibility. It requires less effort than a pseudo-classical template and gives us better encapsulation and information hiding and access to super-methods." But I also saw articles arguing differently, like http://bolinfest.com/javascript/inheritance.php

EDIT ------

If you want to learn different approbations for achievement of super methods, in the Functional template you can do the following:

 Function.prototype.method = function (name, func) { this.prototype[name] = func; return this; }; Object.method('superior', function (name) { var that = this, method = that[name]; return function ( ) { return method.apply(that, arguments); }; }); var archer = function (spec, accuracy) { var that = warrior(spec), super_displayInfo = that.superior('displayInfo'); that.getAccuracy = function() { return accuracy; }; that.setAccuracy = function(value) { accuracy = value; }; that.displayInfo = function (n) { var form = super_displayInfo() form.accuracy = that.getAccuracy(); return form; }; return that; }; 
+1
source

Put functions in prototype ...

 function Warrior(weaponName) { this.weapon = weaponName; } Warrior.prototype = { getWeapon : function() { return this.weapon; }, setWeapon : function(value) { this.weapon = value; }, displayInfo : function() { return { "weapon" : this.getWeapon() }; } }; //---------------------------------- function Archer(weaponName) { Warrior.call(this, weaponName); this.accuracy = "86%"; } Archer.prototype = Object.create(Warrior.prototype); Archer.prototype.constructor = Archer; Archer.prototype.getAccuracy = function() { return this.accuracy; }; Archer.prototype.setAccuracy = function(value) { this.accuracy = value; }; Archer.prototype.displayInfo = function() { return "weapon: " + this.getWeapon() + ", accuracy: " + this.getAccuracy(); }; //---------------------------------- var w = new Warrior("sword"); var a = new Archer("axe"); console.log(w.displayInfo()); // Object {weapon: "sword"} console.log(a.displayInfo()); // weapon: axe, accuracy: 86% 

Edit: fixed recursion

+2
source

All Articles