Why doesn't javascript support default inheritance?

As from the OOPS database, I always use inheritance as a powerful tool for reusing code,

For example, if I write a chess program in OOPS and when I implement the is-a relationship like,

 Class Piece{ int teamColor; bool isLive; Positon pos; int Points; ....... int getTeamColor(){....} ....... }; Class Rook extend Piece{ //`is-a` ...... // No getTeamColor() definition here.. because the parent has the definition. }; Class Pawn extend Piece{ //`is-a` ......// No getTeamColor() definition here.. because the parent has the definition. }; 

I could do this using the has-a relationship in javascript, but the drawback that I see is that I also need to override each function in the derived class.

Example: overriding getTeamColor () again in every rook, knight, pawn, king ... etc.

  var Pawn = function(teamColor,pos){ var piece = new Piece(teamColor,pos); ....... this.getTeamColor = function(){ return piece.getTeamColor(); }; } 

My question is Why javascript does not support classic inheritance as the default option?

+6
source share
5 answers

JavaScript really supports prototype inheritance. What you need here is not classes, but encapsulation of behavior and the possibility of redefinition.

 function Piece() { } Piece.prototype.color = "white"; Piece.prototype.getColor = function() { return this.color } Piece.prototype.move = function() { throw "pure function" }; function Pawn() { } Pawn.prototype = new Piece(); Pawn.prototype.move = function() { alert("moved"); } 

and now:

 var p = new Pawn(); p.color = "black"; > p instanceof Piece 

True

  p instanceof Pawn 

True

 p.getColor() 

"the black"

 p.move() 

warnings ...

This is a basic approach, and there are many libraries that turn this into something familiar to guys who want classes - so to speak.

For example, using JayData you can write the previous one in a more encapsulated form (with the bonus of automatically calling the constructor up the chain:

 var Piece = $data.Base.extend("Piece", { move: function() { throw "pure class" } }); var Pawn = Piece.extend("Pawn", { move: function() { ... } }); var p = new Pawn(); 
+13
source

Because Javascript is not an object-oriented language based on classes , but rather a prototype. This is just a design decision.

In addition, Javascript has never been “designed” for all the things we do with it today (from Node.js to ASM.js). The fact that it still matters is the testament of Brendan Eich & Co. So you may wonder why X or Y was never implemented in JS, but the fact is that we use JS for things that would have been unpredictable 20 years ago.

+7
source

Many good books in various traditional OO languages ​​(including Java, C #, and C ++), in particular, advise against using "implementation inheritance" where possible. Example: Effective Java by Joshua Bloch.

The strange fact is that while implementation inheritance does seem to give the correct “shape” to your code, this does not help you solve the problem; more often than not, this causes problems in the long run.

These authors generally give their blessing instead of the “inheritance interface” - but in a duck type language such as JavaScript, there is no need to explicitly declare such an inheritance.

And in JS, you can “reuse” the same function by simply assigning it as a property for multiple objects. Whatever taste of inheritance you need, you can call it out of nothing.

+1
source

JavaScript doesn't even have real OOP style classes, you just can mimic something like that.

In your example, you can achieve inheritance by doing

 var Pawn = function(teamColor, pos) { Piece.call(this, teamColor, pos); } 

However, you should usually attach methods to the function prototype, and not to any newly created object. In this case, you can simulate inheritance by setting up a prototype chain, for example, as CoffeeScript does:

 var a, b, _ref, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; a = (function() { function a() {} return a; })(); b = (function(_super) { __extends(b, _super); function b() { _ref = b.__super__.constructor.apply(this, arguments); return _ref; } return b; })(a); 
+1
source

The next block of code will “extend” one JavaScript prototype from another and ensure that the “instanceof” operator works correctly for the base and derived classes.

From what I can tell, installing the TestB prototype for the new TestA allows the logical consistency of the instanceof operator.

Passing this TestA gives the new instance all the necessary properties and methods.

The implementation of this method is a kind of balance between stylistic desires and pragmatic. This will work in most browsers, even Internet Explorer, if you are forced to support it. It also helps, because the methods contained in one block "feel" a lot like your traditional OO syntax.

Also, the main reason JavaScript doesn't support the traditional OO style is due to its underlying philosophy. The underlying philosophy is freedom. This freedom is designed to allow developers to create their own styles according to the needs of the project.

 function TestA(){ var me = this; me.method = function(){ } } function TestB(){ TestA.call(this); var me = this; me.otherMethod = function(){ } } TestB.prototype = new TestA(); var test = new TestB(); console.log(test); console.log(test instanceof TestB); console.log(test instanceof TestA); //TestA { method: [Function], otherMethod: [Function] } //true //true 
0
source

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


All Articles