Explain Codes LogoExplain Codes Logo

Does JavaScript have the interface type (such as Java's 'interface')?

javascript
interface-engineering
javascript-patterns
object-prototype
Nikita BarsukovbyNikita Barsukov·Oct 19, 2024
TLDR

JavaScript doesn't have the native support for interfaces like Java. However, you can simulate interfaces using class syntax and certain methods:

class MyInterface { methodA() { throw new Error("Expecting a hero, but found a zero!"); } methodB() { throw new Error("MethodB not found! Has anyone seen it?"); } } class MyClass extends MyInterface { methodA() { // Here comes the hero } methodB() { // Found it! It was under the rug all along. } }

This pattern enforces the MyClass to implement the methods outlined by MyInterface, much like how interfaces specify method signatures.

Interface-like behavior in JavaScript

Although JavaScript doesn't have built-in interfaces, you can emulate this behavior following certain patterns and paradigms.

Method existence verification

You can avoid runtime errors by checking if a method exists before invoking it, caveman style. You just need the trusty typeof operator:

if (typeof obj.mammoth_hunt === 'function') { obj.mammoth_hunt(); } else { throw new Error("Oops! Someone forgot their spear at home!"); }

Even non-enumerable properties can come under your watchful gaze with Object.defineProperty:

Object.defineProperty(MyClass.prototype, 'mammoth_hunt', { value: function() { // Time to hunt! }, enumerable: false });

With great power comes great responsibility

Messing with Object.prototype is a bit like playing with fire — it can warm your house, or burn it to the ground. Create a standalone validation function instead:

function implementsInterface(obj, methods) { return methods.every( method => typeof obj[method] === 'function' ); }

Here, every means every. Not one method less.

Custom method existence check

While implements keyword is being kept a secret by JavaScript, whispering about some future features. In the meantime, let's DIY:

Object.implement = function (obj, methods) { return implementsInterface(obj, methods); };

Remember, this won't enforce strict type checking but it does add an additional safety net.

Constructors and Prototypes

You can implement interfaces in spirit using constructor functions and prototypes. This approach is a bit like expecting your kids to follow in your footsteps:

function Circle() { // Circle related stuff } Circle.prototype = Object.create(Shape.prototype); Circle.prototype.draw = function() { // Draw a Circle, not a square! };

This way, you ensure that any "subclass" of Shape brings its own blueprint for the draw method.

Interface emulation in JavaScript

While JavaScript falls short on interface support, it compensates with powerful patterns and techniques. Let's walk you through some of these:

Method signatures with constant objects

Create an object as a reference template for method signatures and use this as your interface:

const DrawableInterface = { draw: function() { throw new Error('Must implement draw method.'); } };

Interface templates for type adherence

Assign the interface-like object to the constructor's prototype to enforce a basic template:

function DrawableObject() { Object.assign(this, DrawableInterface); } // Developers now have a crystal-clear path to follow. No tripping over tree roots!

Using prototypes for interface behavior

By setting prototypes, developers are nudged to implement methods — just like in an interface:

function Square() { // Square specific properties } Square.prototype = Object.create(DrawableInterface); Square.prototype.draw = function() { // Drawing a Square. Mind the edges! };

Capitalize on JavaScript's elasticity

JavaScript's dynamic structures aid in creating modular components. Mimic interfaces for encapsulated data handling and cleaner, more organized code. Remember: These techniques guide, but don't enforce. No strict bouncer at the door.