Proper Inheritance of Properties and Methods in JavaScript

Constructors utilize prototypes as a means of instantiating new objects. In contemporary JS, the inheritance process involves inheriting from an object, as opposed to constructors or classes. It is important to note that the prototype is the object from which inheritance occurs.


Question:

As a recent convert from C# to Javascript, I have a fundamental question about designing my “classes” and their common properties and methods.

In the following section, I am interested in incorporating “id” as a
common property
with start and stop methods. It is important to note that the “id” will vary among instances of MyDerivedClass. If MyOtherDerivedClass also needs to inherit from MyBaseClass, it would be beneficial for “id” to be a universal attribute in the base. I may need to adjust my thought process to achieve this, and I welcome any suggestions for how to accomplish this in a typical Javascript manner.

var MyBaseClass = function(id){
MyBaseClass.prototype.id = id;    
MyBaseClass.prototype.start = function(){
    console.log('Starting item %s', this.id);
    //...//
    console.log('Started item %s', this.id);
};
MyBaseClass.prototype.stop = function(){
    console.log('Stopping item %s', this.id);
    //...//
    console.log('Stopped item %s', this.id);
};
};
var MyDerivedClass = function(id){    
    MyDerivedClass.prototype.connected = false;
    MyDerivedClass.prototype.id = id; //?????
};
inherit(MyDerivedClass, jsDialTone.common.items.DynamicItem);
// This is the inherit method
var inherit = function(child, base){
var Dummy = function(){};
Dummy.prototype = base.prototype;
child.prototype = new Dummy();
child.prototype.constructor = child;
};
var d1 = new MyDerivedClass('D1');
expect(d1.id).toBe('D1'); // passes
var d2 = new MyDerivedClass('D2');
expect(d1.id).toBe('D1'); // fails, since I modified the prototype.


Solution 1:

Employ

d2.id = 'D2'

in the constructor (though it is actually

this.id = id

), and apply the identical approach for the

connected

marker.

The id value is not identical across instances, making it unsuitable to utilize a shared property on the [[Prototype]].

Typically, it is not recommended to alter [[Prototype]] objects within their corresponding constructor-functions as this action is often illogical and comparable to defining a static (or ”
shared”) variable
in C# or
Java constructor
.


Solution 2:


The solution provided above should address your issue, and here is some additional information to assist you further.

function MyBaseClass(id) {
    this.id = id;
}
MyBaseClass.prototype.start = function() {
    console.log('Starting item ', this.id);
    //...//
    console.log('Started item ', this.id);
};
MyBaseClass.prototype.stop = function() {
    console.log('Stopping item ', this.id);
    //...//
    console.log('Stopped item ', this.id);    
};
function MyDerivedClass(id) {
    MyBaseClass.call(this, id);
}
MyDerivedClass.prototype = Object.create(MyBaseClass.prototype);
var base = new MyBaseClass(1);
var derived = new MyDerivedClass(2);
base.start();
derived.start();

The console should display the following output:


Starting item 1


Started item 1


Starting item 2


Started item 2

  • The first step is to generate the MyBaseClass class, followed by defining its methods on the prototype.
  • Afterward, a MyDerivedClass will be generated that employs the .call() function. This will execute the MyBaseClass function, while explicitly defining

    this

    using the initial parameter.
  • Utilizing Object.create(), the prototype of MyBaseClass is assigned to the prototype of MyDerivedClass.

Take a look at the following links for additional resources.

Prototypal inheritance

The .call() method

JavaScript is weird.

Frequently Asked Questions