Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Abstract base class in JavaScript that can't be Instantiated

I have a class

function Node() {     //implementation } 

and another class

function AttributionalNode() {     this.prototype.setAttr = function (attr) {         this.atText = attr;     }; }  AttributionalNode.prototype = new Node(); AttributionalNode.prototype.constructor = AttributionalNode; 

How to make class Node() so it can't be instantiated? e.g when I try

var node = new Node(); 

So it throws an Exception?

like image 500
Alexandr Sargsyan Avatar asked May 31 '15 15:05

Alexandr Sargsyan


People also ask

Why would you create an abstract class if it can have no real instances?

No, you cannot create an instance of an abstract class because it does not have a complete implementation. The purpose of an abstract class is to function as a base for subclasses. It acts like a template, or an empty or partially empty structure, you should extend it and build on it before you can use it.

Can we create abstract class in JavaScript?

Abstract classes need to be inherited and require subclasses to provide implementations for the method declared in the abstract class. As in Java, we have the abstract keyword to make a class an abstract class, there are no such reserve keywords in JavaScript to declare a class an abstract class.

What word do we use to create a class that Cannot be instantiated?

Abstract Classes and Class Members An abstract class cannot be instantiated. The purpose of an abstract class is to provide a common definition of a base class that multiple derived classes can share.

Is an abstract class and Cannot be instantiated rails?

Put simply: when Rails creates a model as an abstract class it does so without an underlying table. That means that this model can never be instantiated.


2 Answers

In JavaScript engines that support ECMAScript 2015 (aka ES6) class syntax, this can be accomplished using the new.target meta-property:

function Node() {    if (new.target === Node) throw TypeError("new of abstract class Node"); } 

or using class syntax:

class Node {    constructor () {       if (new.target === Node) throw TypeError("new of abstract class Node");    } } 

in either case, just define AttributionalNode as:

class AttributionalNode extends Node {    constructor () {       super();    }    setAttr(attr) {       this.atText = attr;    } }  new Node();               // will throw TypeError new AttributionalNode();  // works fine 

For a more detailed explanation of new.target see section 4.2 of this document.

like image 90
Allen Wirfs-Brock Avatar answered Sep 22 '22 23:09

Allen Wirfs-Brock


This would work:

function Node() {      if (this.constructor === Node) {          throw new Error("Cannot instantiate this class");      }  }    function AttributionalNode() {      Node.call(this); // call super  }    AttributionalNode.prototype = Object.create(Node.prototype);  AttributionalNode.prototype.setAttr = function (attr) {      this.atText = attr;  };  AttributionalNode.prototype.constructor = AttributionalNode;    var attrNode = new AttributionalNode();  console.log(attrNode);  new Node();

Note: you cannot refer to this.prototype inside the constructor, as the prototype is only a property of the constructor function, not of the instances.

Also, see here for a good article on how to properly extend JS classes.

like image 34
levi Avatar answered Sep 19 '22 23:09

levi