Post Archive
› February 22, 2006
OOJS - overhyped and overcomplicating
Yeah, it's blasphemous. But I said it, and I'll clarify it a bit: I see practically no use for writing object oriented code in JavaScript. Lemme explain...
I'll start off by listing some reasons why you would want to use an object oriented approach, as well as an explanation of how they are achieved in JavaScript:
- Typing
JavaScript is strongly (i.e. objects always have a certain type and different treatment requires casting them to another type) but dynamically (i.e. variables are untyped, it's values that have types) typed without type annotations. Types are run time changing as well. Which leads to the fact that you have very little type information at compile time.
- Polymorphism
In JavaScript, all polymorphism is done by run time testing and chosing paths. There are no compiler optimisations, no early binding performance gains, in fact there are no compile time typing constructs at all except for possibly primitive literals.
As a result, there is nothing to be gained performance wise to object orienting your code.
- Encapsulation
Encapsulation in JavaScript is pretty simple. The only black box construct is lexical scoping of functions. There is only one way of making data private, and that is the closure. In the case of object oriented code, you have the constructor closure. That's the encapsulating unit, that's why it's such a pain to get a super "class" and a sub "class" to share private members.
- Inheritance
JavaScript inheritance in done by run time delegation. Unlike classes in classical object oriented languages, prototypes are extendable at run time, so the inheritance scheme needs to be run time as well. Inheritance stretches to properties only, not special behaviors such as arrays increasing their length when extended or being truncated when their length is set to a lower value. Also, all objects are run time extendable, so instead of inheriting you can just add to an object of the more primitive kind.
- Type annotations
JavaScript has no type annotations. This means that you get no function signatures or similar for APIs and libraries. You simply need to deal with any type of input, whether by giving run time errors or by forking your code.
So, I think a sharp minds will see that there is only one of those points left standing, and that's inheritance. But how necessary is inheritance in JavaScript? We can extend any object at run time if we so wish. Code reuse in JavaScript can easily be done at function and object literal level instead of through inheriting properties and methods. (More easily, in fact, since we're not locked to any one single inherited hierarchy.)
Cleaning the global namespace can be done through use of object literals, array literals, function literals and knowing a bit about the production environment the code is going to run in.
Also consider the environment JavaScript can be found in. It's used as a presentational interaction layer in home pages. We're not in an environment where we have a huge data that we need to have a data oriented structure and solid hierarchy. We're in an environment where the language is most often put to the task of performing a few, or hundreds, of pretty simple and essentially unconnected tasks. And I see very little practical use for object oriented code in that setting.
And by that we come to the point I'm trying to make here: Object oriented Javascript has been raised to the skies lately. Well, let's be objective here - let's see what benefits can be gotten from this approach before we raise it to the skies. I think you'll find it far less beneficial even for huge projects than it's gotten a word of being.
Comments
1. February 22, 2006 08:11 AM
2. February 22, 2006 10:44 AM
3. February 22, 2006 01:08 PM
klimas Posted…
You say that JS is best at "performing a few, or hundreds, of pretty simple and essentially unconnected tasks." I don't think the "essentially unconnected" part is true. Often you need to remember some state across function calls -- the most obvious being making a HTTP request and taking action once it completes. An object is a handy way to keep that information together.
I agree with you that inheritance and polymorphism are probably too heavy-duty for most JS applications.
4. February 22, 2006 02:38 PM
ppk Posted…
Amen brother.
Thanks for furnishing the technical details about OO programming and their uselessness in JavaScript. I feel the same, but I couldn't have explained it in OO terms.
5. February 22, 2006 03:47 PM
Dustin Diaz Posted…
Ya know what, I agree! There hasn't been a single thing I haven't been able to get done with the Object Literal. OO JavaScript is definitely something I've put off my list mainly just because I haven't found a practical use for it yet. Not to mention the fact that your browser needs to allocate memory for each instantiation of a new Object. Performance wise, it's best to use the Object Literal :)
6. February 22, 2006 03:48 PM
Hermann Klinke Posted…
I do not agree. Object oriented development in any language makes your code more maintainable and more reusable. I think that encapsulation is extremely important. I hate seeing this ajax tutorials with XmlHttpRequest that are being copy & pasted and then just tweaked a little bit. The maintance is horrible. What's wrong with writing a WebRequest class that can be reused and has events like RequestComplete that call the appropriate methods? Create an instance, set a few properties and it will do everything for you. You can also make it cross browser if you wish. You can simulate everything in javascript (yes, everything, you just need to be a little creative) and use it like any other object oriented language. Procedural code is fine for simple web pages where you just need to manipulate the DOM a little bit, but not for rich web applications aka ajaxified web pages. Way to many people just hack something together creating spagetti code and thus degrading the profession of web developers
Somebody: "What do you do for living?"
Web Developer: "I develop web sites."
Somebody: "Oh, my little nephew does that too!"
Web Developer sighs: "Yeahhh. I know."
7. February 22, 2006 06:34 PM
jm Posted…
liorean wrote: ... I see practically no use for writing object oriented code in JavaScript.
Well, then maybe you should find out first, and tell us about it afterwards.
8. February 22, 2006 07:06 PM
Mark Kawakami Posted…
Well, I know at the lowest levels, these definitions have some vagueness, but I've always maintained that Javascript is Object-Oriented, in that it has an object model, an inheritance model and an encapsulation model (however primitive). The difference from most other OO languages is that it has Prototype-based inheritance rather than Class-based inheritance, but that doesn't negate it as an Object-Oriented language. I think the distinction is important for just this sort of debate: Object-Orientation has tangible real-world value, but that's not really the question. The question is whether or not there is any benefit in shoehorning a Prototype-based language into a Class-based paradigm, which principally means whether there is a benefit to class-based inheritance in Javascript.
I personally feel that a lot of the freedom a Prototype-based language gives you (and the freedom of functions-as-objects) is overlooked by programmers used to Java and the OO C variants. But at the same time, some of that freedom is spent doing things that are accomplished more directly in Class-based languages.
I don't have an answer, of course, I just have precision issues.
9. February 22, 2006 10:16 PM
Jon Posted…
Yeah, at the extreme end of Ajax apps (way past little tricks on a web page), the web server is basically only serving up plain html, and the entire application is in the javascript.10. February 23, 2006 08:13 AM
brothercake Posted…
"Cleaning the global namespace can be done through use of object literals, array literals, function literals and knowing a bit about the production environment the code is going to run in."
But object-oriented code is much easier to read than object based code - you of all people can't deny how terse and difficult to follow an entire script written as an object literal is. OO is much more developer-friendly, which is particularly relevant in multi-programmer projects.
And sometimes you don't know anything about the production environment the code is going to run in.
11. February 23, 2006 11:26 AM
Robert Posted…
Yeah, those pesky Python programmers are really lame for buying into all that OO stuff. Come to think of it, someone should just strip the Python interpreter (get it at python.org) of all that unnecessary "stuff". I'm sure the Python programmers will be glad, and interpretation will probably become a lot faster as well.
/sarcasm off
12. February 23, 2006 12:22 PM
kirinyaga Posted…
OO is useful in JS for reusability. It leads to a "everything in this neat package" paradigm that fits very well with library programming. The powerful prototype & functional orientation of JS is also useful and I use both equally and extensively.
The main problem of JS for me and the main limit to OOJS is the performance. Javascript is about the worst language (including scripting ones) I ever seen ... One of the OO && functional paradigm is to trade a bit of performance against convenience & reusability, and to be able to build applications by stacking packages and libraries that OO allow to work together without you thinking about it. Alas, you cannot do that in JS without meeting major performance issues. Some of the huge AJAX libraries & frameworks floating around are terrible performance-wise because of this.
13. February 23, 2006 05:04 PM
Hermann Klinke Posted…
Hey kirinyaga, do you have benchmarks? According to this, Javascript has very good performance: "In ten years, JavaScript performance has improved a hundredfold." or "So even in the last three years, we've almost doubled the speed of JavaScript." or "Well, our computers are now so fast that-- with very few exceptions-- we don't care how much interpreted code costs any more."14. February 23, 2006 06:22 PM
Tim Parkin Posted…
I'm glad somebody pointed out that *javascript is a programming language*. It is a tool to be used and the way that it is used is not proscribed.
Someone rightly pointed to the parralel between javascript and python (even the next version of javascript is quoted as being 'more pythonic'), what is different about python that makes it *ok* to use oo techniques - after all google uses python in both functional and oo paradigms - or are you making the same case for all 'dynamic' languages.
The comments made suggest that you come from a c/java background and also suggest that your argument is more about performance optimisations than productivity optimisations. I think you've missed the productivity and reusability advantages that come once you've got past the initial pain - although programming in javascript is nowhere near as freindly as programming in python
15. February 24, 2006 05:00 PM
Austin Barnes Posted…
Quoting TomI'm currently reading the Ajax book "Ajax in action" and the authors are fully immersed in OO JavaScript, including modeling code after MVC frameworks, setting up facades and everything.
I recommend that the author of this thread (and anyone interested in JavaScript at all) read this book, "Ajax in Action," by Dave Crane and Eric Pascarello. It's an excellent book and expose of, well literally, Ajax in Action. Very practical, and very elegant.
This book illuminates the advantages of an OO-like style in Javascript. But not in the convential OO sense of strict inheritance and polymorphism. Really, sometimes, it reads more like closures in disguise. Again, if there is two programming books you read this year, make this one of them.
I think the difference between OO and closures is on a scale, like the difference between black and white can be measured in shades of gray. What is at question is people's measurements and biases to different meanings of OO (Java, C++, ect) and closures (Lisp, Python, ect.).
My opinion at this point is that both orientations have numerous advantages, and in any given domain, we should always seek the simplest solution: whether that be an OO-esq solution, closures, or hybrids.
I think it was Einstein who said that a fool can make anything more complex, but it takes a genius to make something simple. Since my description so far lacks any genius, I'm just trying to make things simplier here.
So my guess is: use OO where appropriate to accomplish a practical goal. Strict OO may be more useful in a multi-programmer environment, or to keep track of code as the codebase grows. If not strict OO, some other set of agreed upon rules must be found to make real practical progress. For instance, the Actor model. However, for convience, the basic concepts of OO are relatively well-known, and so are more useful presently, in common-demonitator team situations, than say Lisp-style bottom-up programming -- with which few are directly and intimately familiar.
Of course, if your working with mostly Python hackers, you might want to challenge them with closure-type rules... where it seems you can do more with less effort, but you are more at risk for stepping on other team member's toes.
Either way, thanks liorean for taking your staunch approach in your article. This enables readers and commenters to quickly get a "diff" of what actually matters in the discussion. Proponents scream their "best" arguments, and so do opponents, which allows for an expedited understanding of the argument's essense.
16. February 28, 2006 07:37 PM
Jonathan Buchanan Posted…
"There hasn't been a single thing I haven't been able to get done with the Object Literal."
How about having state and behaviour in one logical entity, of which there may be a number of instances in the system, which may be used by different components in the system? That gets pretty messy if the state you're operating on and the functions which operate on that state are separate (for example, an object literal containing an array of object literals representing the state and a load of functions which operate on that state). Especially once you start wanting to be able to pass entities around.
Sure, this can be done with an object literal, but it's cleaner and generally more pleasant to work with (and maintain) if you're using OO - myRecord.getDuration() versus someObjectLiteral.getDuration(myRecordStateObject) - I know which one I want to write the unit tests for ;-)
I suppose it depends on the problem at hand and whether or not you're doing any significant modelling of the problem on the client side. If you are, and you have a sufficiently interesting problem to solve, modelling it as a set of interrelated objects, each of which looks after their own concerns, is likely to be the more elegant, maintainable and reusable design.
Of course, it's really about choosing an implementation which is appropriate for the task at hand, rather than forcing yourself to do it one way: there's no point creating an OO solution if all you really require is a container for a few utility functions and some simple state; it's not going to be fun modelling a complex system using object literals alone.
17. March 2, 2006 09:25 AM
ep Posted…
OO is a powerful tool for communicating your desing ideas to fellow coders. It's unnecessary if you don't have a need for such communication, or you can achieve it by other means.
18. March 9, 2006 09:13 AM
Nevel Posted…
I have to disagree. In some cases I like using JS objects in order to keep my code "clean". For example: no more value arrays of which the items correspond to each other, but several instances of the same object with different values attached to it...
19. March 29, 2006 10:33 AM
Warren Posted…
All of your reasons for why Javascript makes a poor OO language make me realize just how great of an OO language JS really is. You sound like you want JS to be more like Java, but JS has some great OO features that Java lacks (like open types and dynamic typing). Everyone is raving about Ruby these days because it has these same features that you think are overkill in JS.
In my opinion, JS does have problems, but they have more to do with the fact that JS was neglected for a very long time during the browser wars. They also have a lot to do with the fact that the DOM api (for all languages, not just JS) is really horrible.
Perhaps OO progamming on the web for simple event handling is overkill, but that's not a problem with JS, it's a problem with the nature of the web.
Tom Posted…
Wow Liorean! Well, I'm certainly not as well versed in the language (or OO concepts) as you are. I'm currently reading the Ajax book "Ajax in action" and the authors are fully immersed in OO JavaScript, including modeling code after MVC frameworks, setting up facades and everything.
I think the issue you make is that JS is used as a "presentational interaction layer in home pages." Sure, in that case, probably you are right. However, what about when JS is being used as an application base?
In many of these Ajax applications, it's the JS that *is* the application for the most point. Sure, lot's of stuff may be happening on the server, but the JS is in control. And you aren't simply downloading a hundred or so lines of code, you're probably using a couple libraries and downloading thousands of lines of code.
Certainly at that point in behooves us to consider OO concepts and get some benefit? I would at least think in terms of organization and good coding practices that these things would be helpful. I know that even though some of these concepts in Ajax in action are a smidge beyond me at the present, it has already taught me much and made me a better programmer.
I know you aren't advocating "bad code" or sloppy code. But shouldn't we strive to bring up the quality level of JS from where it has been in the past? Silly counter scripts, pop up windows, news tickers and myriads of bad uses of JS have plagued the web since the 90's. Even if there is no actual performance gain, I'd like to think there is some kind of gain to the community in general where we simply write "better" code.
Lots of "web 2.0" tech is overhyped right now for sure, but in my mind OOJS is one good thing to come out of it. Maybe it doesn't give us the gains that it might in a language like Java, but my hope is that it makes those of us who love JS better programmers and scripters, regardless.
Tom