I am a programmer who has programmed in several languages, both functional and OO oriented. I programmed some Javascript too, but never used (or had to use) polymorphism in it.
Now, as kind of a hobby project, I would like to port some apps that were written in Java and C# that heavily use polymorhpism to Javascript.
But at a first glance I read lots of 'It's possible but ...'
So is there an alternative to it?
An example of what I would like to write in JS in pseudolang :
abstract class Shape{ { printSurface() } ; } class Rect : Shape() { printSurface() { print (sideA*sideB}} class Circle : Shape() { printSurface() { print { pi*r*r }} TheApp { myshapes.iterate(shape s) {s.printSurface() } }
So a classic polymorphic case : iterating over baseclass.
I would like to achieve this kind of behaviour. I know it is polymorhism, but are there any other 'patterns' that I am overlooking that achieve this kind of behaviour or should I study the inheritance possibilities in Javascript?
Polymorphism with Functions and Objects: It is also possible in JavaScript that we can make functions and objects with polymorphism. In the next example, we will make two functions with the same name 'area'. In class A, we define the area function. In this function, we have two parameters.
Polymorphism is inherently good. It refers to something having many forms, referring to both objects and methods. Polymorphism allows you to code to an interface that reduces coupling, increases reusability, and makes your code easier to read.
Polymorphism is the ability to define a generic type of behaviour that will behave differently when applied to different types. Let's say we have an Animal class that implements the talk method. If class Dog and Cat inherit talk() from class Animal, object dog and object cat both will talk but in a different form.
JavaScript is not a class-based object-oriented language. But it still has ways of using object oriented programming (OOP).
As said, JavaScript is a dynamic typed language based on prototypal inheritance, so you can't really use the same approach of typed languages. A JS version of what you wrote, could be:
function Shape(){ throw new Error("Abstract class") } Shape.prototype.printSurface = function () { throw new Error ("Not implemented"); } function Rect() { // constructor; } Rect.prototype = Object.create(Shape.prototype); Rect.prototype.printSurface = function() { // Rect implementation } function Circle() { // constructor; } Circle.prototype = Object.create(Shape.prototype); Circle.prototype.printSurface = function() { // Circle implementation }
Then, in your app:
var obj = new Circle(); if (obj instanceof Shape) { // do something with a shape object }
Or, with duck typing:
if ("printSurface" in obj) obj.printSurface(); // or if (obj.printSurface) obj.printSurface(); // or a more specific check if (typeof obj.printSurface === "function") obj.printSurface();
You cold also have Shape
as object without any constructor, that it's more "abstract class" like:
var Shape = { printSurface : function () { throw new Error ("Not implemented"); } } function Rect() { // constructor; } Rect.prototype = Object.create(Shape); Rect.prototype.printSurface = function() { // Rect implementation } function Circle() { // constructor; } Circle.prototype = Object.create(Shape); Circle.prototype.printSurface = function() { // Circle implementation }
Notice that in this case, you can't use instanceof
anymore, so or you fallback to duck typing or you have to use isPrototypeOf
, but is available only in recent browsers:
if (Shape.isPrototypeOf(obj)) { // do something with obj }
Object.create is not available in browser that doesn't implement ES5 specs, but you can easily use a polyfill (see the link).
The "pattern" in play here would be "interface". As long as all the objects in the myshapes
collection implement the printSurface()
method, you will be fine.
Since Javascript is a dynamically typed language, the objects in a collection don't need to be related at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With