Interview question
How do abstract-like classes and interfaces work in JavaScript, since it doesn't natively support them? JavaScript में abstract-jaisi classes और interfaces कैसे काम करते हैं, जबकि native support नहीं है?
Answer
JavaScript has no built-in 'abstract class' or 'interface' keywords, but the same design intentions can be enforced manually using constructor checks and method existence checks.
// Simulating an abstract class - prevents direct instantiation
class Shape {
constructor() {
if (new.target === Shape) {
// new.target refers to the constructor actually called with 'new'
throw new Error('Shape is abstract and cannot be instantiated directly');
}
}
area() {
throw new Error('area() must be implemented by subclass'); // enforced 'abstract method'
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() { // required override
return Math.PI * this.radius ** 2;
}
}
// new Shape(); // Error: Shape is abstract and cannot be instantiated directly
const circle = new Circle(5);
console.log(circle.area()); // 78.53...
class Triangle extends Shape {
// Forgot to implement area()
}
const triangle = new Triangle();
// triangle.area(); // throws 'area() must be implemented by subclass'
// Simulating an interface via a checking function (duck typing)
function implementsInterface(obj, methods) {
return methods.every(method => typeof obj[method] === 'function');
}
class FileLogger {
log(msg) { console.log('File:', msg); }
error(msg) { console.log('File error:', msg); }
}
const logger = new FileLogger();
console.log(implementsInterface(logger, ['log', 'error'])); // true
// TypeScript's interfaces solve this problem at COMPILE time instead;
// in plain JS, these runtime checks are the closest equivalentJavaScript में built-in 'abstract class' या 'interface' keywords नहीं हैं, पर वही design intentions constructor checks और method existence checks से manually enforce की जा सकती हैं।
// Abstract class simulate करना
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error('Shape abstract है, directly instantiate नहीं हो सकता');
}
}
area() {
throw new Error('area() subclass में implement होना चाहिए');
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
}
// new Shape(); // Error
const circle = new Circle(5);
console.log(circle.area()); // 78.53...
class Triangle extends Shape {
// area() implement करना भूल गए
}
const triangle = new Triangle();
// triangle.area(); // Error throw होगा
// Interface simulate करना - duck typing
function implementsInterface(obj, methods) {
return methods.every(method => typeof obj[method] === 'function');
}
class FileLogger {
log(msg) { console.log('File:', msg); }
error(msg) { console.log('File error:', msg); }
}
const logger = new FileLogger();
console.log(implementsInterface(logger, ['log', 'error'])); // trueWas this answer clear?