In JavaScript, there are many different ways of inheritance, class and prototype, factory and through impurities, direct and indirect, as well as hybrids of several methods. But Node.js has its own native method using util.inherits (ChildClass, ParentClass). Until recently, I used the Nod method only for the built-in classes (when you need to make your successor for the EventEmitter, Readable / Writable Stream, Domain, Buffer, etc.), and for common domain modeling I used common practices for the entire JavaScript. And here, for the first time, it took to implement its own hierarchy of system classes, not inheritors from the built-in, but not the domain classes, but the classes massively affected in the system code of the Impress application server. And the simple use of util.inherits was somehow not enough, I looked for the article and didn’t find everything I needed, studied the examples of inheritance in the source code of the node itself, thought and made an example of the native node inheritance as a memory and wrote this small note, so that she, I hope, will also help you. Immediately I warn you that I don’t really like the implementation of the method call of the parent class from the method overridden in the child class because of the bulkiness, therefore, I welcome alternative ways and invite you to commit them to the repository or in the comments to this note.var util = require('util'); // function ParentClass(par1, par2) { this.parentField1 = par1; this.parentField2 = par2; } function ChildClass(par1, par2) { ChildClass.super_.apply(this, arguments); this.childField1 = par1; this.childField2 = par2; } // util.inherits(ChildClass, ParentClass); // var obj = new ChildClass('Hello', 'World'); console.dir({ obj: obj }); /* : { obj: { parentField1: 'Hello', parentField2: 'World', childField1: 'Hello', childField2: 'World' } } */ var util = require('util'); // function ParentClass(par1, par2) { this.parentField1 = par1; this.parentField2 = par2; } // ParentClass.prototype.parentMethod = function(par) { console.log('parentMethod("' + par + '")'); }; // ParentClass.prototype.parentField = 'Parent field value'; // function ChildClass(par1, par2) { ChildClass.super_.apply(this, arguments); this.childField1 = par1; this.childField2 = par2; } // util.inherits(ChildClass, ParentClass); // ChildClass.prototype.childMethod = function(par) { console.log('childMethod("' + par + '")'); }; // ChildClass.prototype.childField = 'Child field value'; // var parentClassInstance = new ParentClass('Marcus', 'Aurelius'); var childClassInstance = new ChildClass('Yuriy', 'Gagarin'); // console.dir({ parentClassInstance: parentClassInstance, childClassInstance: childClassInstance }); console.dir({ objectFieldDefinedInParent: childClassInstance.parentField1, classFieldDefinedInParent: childClassInstance.parentField, objectFieldDefinedInChild: childClassInstance.childField1, classFieldDefinedInChild: childClassInstance.childField }); parentClassInstance.parentMethod('Cartesius'); childClassInstance.childMethod('von Leibniz'); /* : { parentClassInstance: { parentField1: 'Marcus', parentField2: 'Aurelius' }, childClassInstance: { parentField1: 'Yuriy', parentField2: 'Gagarin', childField1: 'Yuriy', childField2: 'Gagarin' } } { objectFieldDefinedInParent: 'Yuriy', classFieldDefinedInParent: 'Parent field value', objectFieldDefinedInChild: 'Yuriy', classFieldDefinedInChild: 'Child field value' } parentMethod("Cartesius") childMethod("von Leibniz") */ var util = require('util'); // function ParentClass(par1, par2) { this.parentField1 = par1; this.parentField2 = par2; } // ParentClass.prototype.methodName = function(par) { console.log('Parent method implementation: methodName("' + par + '")'); }; // function ChildClass(par1, par2) { ChildClass.super_.apply(this, arguments); this.childField1 = par1; this.childField2 = par2; } // util.inherits(ChildClass, ParentClass); // ChildClass.prototype.methodName = function(par) { // ChildClass.super_.prototype.methodName.apply(this, arguments); // console.log('Child method implementation: methodName("' + par + '")'); }; // var childClassInstance = new ChildClass('Lev', 'Nikolayevich'); // childClassInstance.methodName('Tolstoy'); /* : Parent method implementation: methodName("Tolstoy") Child method implementation: methodName("Tolstoy") */ This construct for calling the parent class method is of course very cumbersome: ClassName.super_.prototype.methodName.apply (this, arguments) but I did not find another way for the native Nodal implementation of inheritance. The only dubious improvement that occurred to me was given in the following example. var util = require('util'); // Function.prototype.override = function(fn) { var superFunction = this; return function() { this.inherited = superFunction; return fn.apply(this, arguments); }; }; // function ParentClass(par1, par2) { this.parentField1 = par1; this.parentField2 = par2; } // ParentClass.prototype.methodName = function(par) { console.log('Parent method implementation: methodName("' + par + '")'); }; // function ChildClass(par1, par2) { ChildClass.super_.apply(this, arguments); this.childField1 = par1; this.childField2 = par2; } // util.inherits(ChildClass, ParentClass); // ChildClass.prototype.methodName = ParentClass.prototype.methodName.override(function(par) { // this.inherited(par); // this.inherited.apply(this, arguments); // console.log('Child method implementation: methodName("' + par + '")'); }); // var childClassInstance = new ChildClass('Lev', 'Nikolayevich'); // childClassInstance.methodName('Tolstoy'); /* : Parent method implementation: methodName("Tolstoy") Child method implementation: methodName("Tolstoy") */ var util = require('util'); // function override(child, fn) { child.prototype[fn.name] = fn; fn.inherited = child.super_.prototype[fn.name]; } // function ParentClass(par1, par2) { this.parentField1 = par1; this.parentField2 = par2; } // ParentClass.prototype.methodName = function(par) { console.log('Parent method implementation: methodName("' + par + '")'); console.dir({t1:this}) this.parentField3 = par; }; // function ChildClass(par1, par2) { ChildClass.super_.call(this, par1, par2); this.childField1 = par1; this.childField2 = par2; } // util.inherits(ChildClass, ParentClass); // override(ChildClass, function methodName(par) { // methodName.inherited.call(this, par); // console.log('Child method implementation: methodName("' + par + '")'); this.childField3 = par; }); // var childClassInstance = new ChildClass('Lev', 'Nikolayevich'); // childClassInstance.methodName('Tolstoy'); /* : Parent method implementation: methodName("Tolstoy") Child method implementation: methodName("Tolstoy") */ Source: https://habr.com/ru/post/247325/
All Articles