JavaScript Doesn't Need Class
Written by Ian Elliot   
Friday, 18 November 2011
Article Index
JavaScript Doesn't Need Class
JavaScript Doesn't Need Type

JavaScript is the single most important programming language and yet, as it reaches its high point, everyone is complaining about it and there are significant efforts to replace it with something better - Go, Dart, Coffeescript. Even the people who love it seem to misunderstand it because they want to add "class". JavaScript doesn't need class! And if you think it does you need to look more carefully at JavaScript.

I often have conversations with JavaScript programmers and make the point that the language needs to be treated as itself rather than as a poor relation to Java or some other language. They usually agree vigorously and then go into details about how some framework or other gives them facilities just like class and inheritance - just like Java or C# or... Well you get my point, or I hope you do.

JavaScript really is a very different language.

It is one of the few mainstream languages that doesn't simply mimic the C/C++ way of doing things. It is also quite different in terms of its treatment of objects. The problem here is that programmers tend not to spend the time to find out what these differences are. They simply notice that it doesn't have "class" and it doesn't seem to have inheritance and then they spend lots of time inventing ways to add them or, worse they propose an upgrade to the language that adds them.

First off it isn't clear that "class" is the best way to work with objects, and it certainly isn't clear that class-based inheritance is even good, let alone the best.

We are simply following the conventions of what already know when identifying these omissions in JavaScript. Class-based programming was invented to make compilers work better and to make errors detectable at compile time rather than run time.

The argument goes that in a strongly typed, class-based, langauge you can't assign apples to oranges because they are different types. This is fine, but the real question is why any programmer would make the mistake of assinging apples to oranges; and what is it about the way apples behave that make this even thinkable. Is it that perhaps apples have a method in common with oranges that suggest that they can be used in the same way? In which case perhaps the language should make an attempt to work out what the programmer intended rather than just flagging a type error.


I'm not saying that either approach is always correct, just that the answer isn't as clear cut as you might expect.

Introducing strongly typed objects creates a new class of errors.

If you don't believe me just check out the reaction of a beginner when told that they can't do something like:


because 1 is an integer and not a string. Yes this is all true but how brainless the compiler is that it doesn't know how to do the conversion.

JavaScript implements objects in a type free dynamic way and this is very different and it deserves a chance to show what it can do before you attempt to squeeze it into the old straitjacket of type, class and inheritance.

So the points at issue are:

1) JavaScript doesn't benefit from anything like a "class" construct.

2) Class-based inheritance is a nonsense in JavaScript

3) JavaScript's prototype object construct isn't an example of a broken inheritance mechanism, but something quite different.


Lets see how all this works.

In JavaScript everything is an object and functions are objects too. This is a wonderful simplification and once you "get it" you just feel sorry for all those languages that have to invent delegates, function pointers, lambda expressions and so on just to make up for the error of not making functions full or first class objects.

The only native data structure in JavaScript is the associative array or hash and objects are simply associative arrays. This means that object construction is just a matter of initializing an associative array. You can do this as an object literal which is a great way of creating a singleton.

If you want to create lots of instances then you need to write a function (which is an object) to create another object. That is you create a function which spits out the object you really want to create.

You don't have to make use of the constructor facilities provided by JavaScript - i.e. the new operator and the prototype and constructor properties but this has some advantages. You can simply write a function that builds an associative array and returns it as the new instance of the object.

Notice that you don't need the notion of a "class", i.e. a meta construct that defines the workings of an object so that an instance can be created in what appears to be a single declaration. JavaScript objects are actively constructed and not declared as if they were static entities.

This fits in perfectly with JavaScript's dynamic objects. At any time you can add a method or a property to an object and you can similarly remove them. JavaScript objects can morph and there is no need to have a single constructor. You can take an existing object and augment the object by adding anything you like. You can even write a partial object factory which simply adds a set of properties and methods to an existing object.

Notice that if you have dynamic objects in a language then you don't need to worry about the object's type and hence you don't need to worry about inheritance. Inheritance is the classical way of extending the type system. You start off with a base type, usually Object, and you increase the number of types by inheritance. The result is a type hierarchy and a set of complicated rules that govern what types can be used where - subclassing, up casting, down casting, covariance, contravariance etc.. And then to make everything more powerful you invent generics which allow you to write algorithms that are type independent.

Inheritance and strong typing go together.

Don't misunderstand my meaning. Strongly typed object-oriented languages are great, but they are not the only way of doing the job and they are not provably the best way.




Last Updated ( Friday, 18 November 2011 )