OOP vs JavaScript - javascript

I have a background in OOP. I started to work a lot with JavaScript. As the project grows it's becoming more difficult to maintain it. In Java I apply OOP principles to keep things under control. What should I do with JavaScript, what should I study that is aimed at keeping a JavaScript application under control?

You can apply OOP principles to Javascript development too. Javascript uses prototypal inheritance, but that is an implementation detail. The concepts are still the same. Most of the concepts with which you are familiar have direct analogues in javascript.
Other tried and true methods apply as well:
1) Stay DRY -- Do not Repeat Yourself. Duplicate code is always evil.
2) Separate concerns -- Use the MVC or MVVM patterns to keep code clean and doing only 1 thing.
3) Test -- When I hear "Difficult to maintain" my brain translates that into lack of tests. You can certainly write unit tests for javascript projects.
4) Code Review -- Code reviews can be a good way of rejecting duplicated code, code that is not crafted properly, not formatted, etc....

This is how you define objects and methods in javascript.
function SomeObj() {
this.someMethod = function() {
alert('boo');
}
}
var o_obj = new SomeObj();
o_obj.someMethod(); //alerts "boo"
Hope it helps.
You can also use prototype to create static functions.
this.prototype.someMethod = function() {
alert('boo');
}

When I was in the same situation I started to look at "how other did". Its ended up with http://dojotoolkit.org/ and http://jquery.com and I was looking how they implement widgets/plugins so other could extend the framework.

Another way of defining simple objects and methods in javascript (without the need for new).
function creaeSomeObj() {
var that = {};
that.someMethod = function() {
alert('boo');
}
return that;
}
var o_obj = createSomeObj();
o_obj.someMethod(); //alerts "boo"
This pattern doesn't support inheritance, but many times it is sufficient.

Why "vs"? JavaScript supports object-oriented programming, but not in the traditional class-based way that you see in e.g. Java.
The way JavaScript's OOP works is usually known as "prototypal inheritance", or more specifically "delegative prototypal inheritance". This can be boiled down to "if you're looking for the property 'foo' in an object, and you can't find it there, then try looking for 'foo' inside the object's prototype instead". That is, the lookup of the property is delegated to the object's prototype (we say that the object inherits the properties from the prototype).
The way prototypal inheritance works has a couple of implications. For instance:
Objects in JavaScript are "dynamic" in the sense that they're just a bunch of name-value pairs. New properties can be added and removed during runtime, so they're much less "static" than objects in the typical class sense.
The way delegative prototypal inheritance works ("if you can't find the prototype here, then look here instead") means it's much simpler than classical OOP. From a purely prototypal point of view, you don't need constructors, for example. "Methods" are just regular functions that happen to be attached to the prototype (which means they are available as properties on all inheriting objects).
There are pro's and con's with both prototypal and classical inheritance, but it's important to remember that they're different.
Now, JavaScript is in some senses inspired by Java and other classical languages, so therefore they decided to make the syntax "class-like" to make it easier for people used to classes to get started. I won't elaborate a lot on this; it's documented to a great extent in other places already.
Some interesting posts:
hughfdjackson's introduction to JavaScript OOP -- short and more to-the-point,
Sorella's longer "Understanding Javascript OOP" -- rather in-depth and very complete resource.

Pluralsight has a course on just this topic: Structuring JavaScript Code that may provide some insight. Two caveats: 1. I haven't sat through the course yet - but content looks great and I've been impressed with other Pluralsight courses I've taken, and 2. it is not free (but may be worth the small $ if it saves you time down the road b/c you have better code structure). No, I don't work for Pluralsight.
In addition to the js frameworks mentioned in this thread, can also look at Knockoutjs - great tutorials here learnknockoutjs.com. Knockout is MVVM focused. Note, there is a good discussion in stackoverflow comparing Backbone to Knockout, and Pluralsight also has a course on using Knockout which I have watched and do recommend.

In JavaScript, Functions are Objects; Mozilla Developer Network, McKoss, SitePoint, and JavaScript Kit explain further.
Example JavaScript Object
function myObj() {
this.myMethod = function() {
alert('hello');
}
}
var demo_obj = new myObj();
demo_obj.myMethod();
Patterns to keep things under control
The patterns listed here are particular to JavaScript.
Use a Script Loader.
Use a JS Framework.
Lint your JavaScript. - Tools are availble to run this on your desktop in Rhino or node.
Minify your JS.
The patterns listed here are typical of OOP Languages, and are not
particular to JavaScript.
DRY - Don't Repeat Yourself.
Observer (Pub/Sub) pattern.
Anti-Patterns to let things out of control
Polluting the namespace
use of eval()
Prototyping against the Object object
Inline Script Tags.
use of document.write

Related

How to write a tidy and flexible complex javascript application using prototypal inheritance

For a while now I have been developing javascript applications, usually smaller scripts to accomplish simple tasks but also a fairly large and complex application using Dean Edwards' base2 library for creating pseudo classic OO classes with inheritance,... in javascript.
The base2 library served me pretty well, mainly because it enabled me to follow the classic OO paradigm, which I am quite familiar with. I also know of several other frameworks that can be used to build more robust and mature javascript applications (backbone.js for example). But I always have the feeling that this type of library is a way of 'cheating', to construct a way to write code using principles the language actually isn't suited for.
I have been reading up on different ways to define objects/functions, instantiate them and achieving polymorphism using prototypal inheritance. This is really how the language works at a fundamental level and I feel like I should take advantage of that rather than deciding it is annoying or strange and trying to find a way to do things the way I'm used to (the classical OO way).
So, looking at applications that are not using this type of library, there seem to be so many ways to write your application while for traditional general purpose languages like Java, C++, ... the right way of building your applications seems more clearly defined (it's a lot easier to distinguish good from bad code). If somebody would ask me tomorrow: "start developing projectX for me", I would have no idea how to start defining and structuring my objects in a way I can be sure won't come back to bite me later when it's too late to restructure the whole thing.
What would a professional complex js app skeleton look like, using prototypal inheritance, so without using any type of library for mimicking classic OO, assuming a simple MVC type of app but easily scalable to more complex proportions. How to define my objects? How to keep objects/'classes' grouped together (namespacing)? In other words: how to do it without ending up with a mess nobody understands anymore?
There are two patterns I follow in creating object oriented Javascript 'classes' (thought there are no real classes in JS, we can mimic them). First is more familier OO way and simple to understand.
// in JS, functions can be used as OO classes
var Person = function(name) {
var self = this;
//private methods and attributes
this.getNickname = function(){
return "Yaka";
};
//public methods and attributes (return obj)
return {
getName : function() {
return name + ' ' + self.getNickname();
}
}
};
//static functions attached to 'Person' class
Person.hasBrain = function() {
return true;
}
This model lets you to have private, public and static sections for your classes allowing good encapsulation. But this not the optimal way as every object will carry it's own copy of all instance methods. You can avoid having multiple copies of the instance methods with prototype based programming:
// in JS, functions can be used as OO classes
var Person = function(name) {
this.name = null;
};
// use of prototypes improves performance and memory use
Person.prototype.getName = function() {
return this.name;
}
Person.prototype.setName = function(name) {
this.name = name;
}
This doesn't look very familier for traditional OO programmers, but the optimum way for using javascript resources. It goes well with inheritance too.
var Manager = function() {}
Manager.prototype = new Person();
In practice I use the prototypical approach for base/framework classes that are being used heavily in the application. For classes being used occasionally or for few instances, I use the approach discussed before.
I also recommend you to use an AMD library such as requirejs, and define a single class per physical file. Then use an build optimizer to optimize your files in to a single script.
I copied above 2 approaches from the unit tests in BoilerplateJS reference architecture. Have a look at the code in BoilerplateJS, it will give you more ideas on how to approach complex application development with JS.
Disclaimer: I'm the main author of BoilerplateJS

What is a good example of OOP that also uses traits in JavaScript?

I have been using Traits.js and/or JSTraits, but I'm having a lot of difficulty combining OOP and the concept of traits in some instances. Is there a good example showing inheritance, complex object instantiation, and traits?
I would like to avoid builder functions, if possible, and still be able to use 'new Foo()' to construct instances.
I eventually gave up and decided to use Coffeescript's little class mechanisms, and rolled my own mixin code like everyone else on the planet.

Does using prototypes in JavaScript have any real world advantages?

I just finished Doug Crockford's The Good Parts, and he offers three different ways to go about inheritance: emulation of the classical model, prototype-based inheritance, and functional inheritance.
In the latter, he creates a function, a factory of sorts, which spits out objects augmented with desired methods that build upon other objects; something along the lines of:
var dog = function(params) {
// animal is the 'super class' created
// the same way as the dog, and defines some
// common methods
var that = animal(params);
that.sound = 'bark';
that.name = function () {};
return that;
}
Since all objects created this way will have a reference to the same functions, the memory footprint will be much lower than using when using the new operator, for instance. The question is, would the prototype approach offer any advantages in this case? In other words, are object prototypes somehow 'closer to the metal' that provide performance advantages, or are they just a convenience mechanism?
EDIT: I'll simplify the question. Prototypes vs. their emulation through object composition. So long as you don't require all object instances to get updated with new methods which is a convenience offered only by prototypes, are there any advantages to using prototypes in the first place?
I emailed Doug Crockford, and he had this to say:
[Using the functional approach above vs. prototypes] isn't that much memory. If you have a huge number of objects times a huge number of methods, then you might want to go prototypal. But memories are abundant these days, and only an extreme application is going to notice it.
Prototypes can use less memory, but can have slightly slower retrieval, particularly if the chains are very long. But generally, this is not noticeable.
The instances don't all reference the same functions etc. Each call to "dog" will create a new "name" function instance.
There are many opinions about this, and Crockford's isn't necessarily the right one.
The main disadvantage to modifying the prototypes is that it may make it harder to work with other javascript libraries.
But the disadvantage of Crockford's functional way of creating classes is that you can't add a method or field to all instances of a type as easily.
See Closure: The Definitive Guide for some critical comments on Crockford's view about classes and inheritance in javascript:
http://my.safaribooksonline.com/9781449381882/I_sect1_d1e29990#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODE0NDkzODE4ODIvNTE0
Libraries like Dojo, Google Closure Library (which seems to copy Dojo's style), and perhaps YUI have their own class system that seems to be a good middle ground. I like Dojo's system probably the best because it has support for Mixins, unlike Closure. Some other class systems not tied to gui toolkits include Joose, JS.Class, and JavascriptMVC (check out last one esp. if using jquery).
I once created a GUI that was backed by a class that didn't have great event-based support for the information it needed. The GUI implemented a generic interface where an instance of that class is passed in, so I cannot inherit from that class, so I did something similar to prototype-based inheritance, I created a proxy object that wraps the instance of that class when it's passed to my GUI. The proxy intercepts methods of interest that mutate state, and report them as events. The entire GUI then revolved around using these events.
In this case, it would have just been annoying to create a separate class that wraps the passed in instance and reproduces the same interface. This would actually have lead to more overhead (not that it matters) due to creating all the redundant functions.
There was simply no other viable alternative. The only alternatives were:
Create an object that composes the object passed to the GUI (like I mentioned above). This object would then reproduce every function in the original class to implement the same interface, and add events, so it's effectively just the same as the proxy object way.
Have the GUI track state mutation in its passed in object. This would have been a pain and bug prone.

Why to use class based OOP style inheritance in javascript?

If I'm not completely wrong every framework/library/approach in javascript tends today to mimick class based OOP style inheritance. Reasons for this seem to be people thinking class based OOP inheritance is far easier to understand and that most programmers know OOP.
In my experience I don't find evidence for either of this opinions. I think javascript prototypal inheritance is just fine (and I doubt the usefulness to force another paradigm upon a language than the one it is built on). Most of the developers I meet aren't even that good in classical OOP either. So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?
I think the answer is in your question - most programmers are far more familiar with class-based OOP than prototype-based.
In fact I'd go so far as to say the majority don't believe you can have objects without classes.
note that even if you're arguing for prototype-based OOP, you call it 'prototypal', and class-based OOP just 'OOP'. so, you yourself suffer from this bias, thinking OOP=>classes, prototypes => something else.
and since most people think that OOP is the right way no matter the problem, then prototypes must be inferior.
so, to answer your question, it's two factors:
a bad definition: "OOP => classes"
propaganda: "it must be OOP, or you're not worthy"
since you're still bounded by the first, you try to explain that prototypes are an exception of the second. much easier is to correct them:
there are many ways to do objects, classes are just the easiest one for static languages. most people are taught to program with static languages, and most of them try to use any language just like the first one they learned.
there are many ways to structure a programming solution, OOP are great at some and lousy at others.
I feel as if you already know the answer to your question because you stated a part of it when you said
Reasons for this seem to be people
thinking class based OOP inheritance
is far easier to understand and that
most programmers know OOP.
Neither paradigm is more right than the other for tackling a problem. I believe the main reason is that everyone is taught OOP through Java these days. So when people encounter OOP they think "oh classes" because it's what they are familiar with. And whenever they want to solve a problem they will most likely use what they know.
I would also state that it does no benefit for the programmer to use a paradigm he is unfamiliar with. Most of us must use javascript for client side web development and use a class based OOP language on the server. I personally would not want that OOP impedance mismatch whenever I had to look at the javascript side of an application.
At a certain level the fact that everyone is trying to implement class based OOP in javascript is an educational issue. At another level it's a psychological one.
For a long time I considered prototype-based OOP as weak, bad and wrong version of class-based OOP. Then, after a critical amount of information leaked into my head, I now understand OOP in more abstract way, and find both ways acceptable in general.
So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?
Actually, I believe that some frameworks are "sort of" combining approaches. Take for example the Parasitic Combination Inheritance pattern. This is what YAHOO.lang.extend is doing.
It uses prototypal inheritance and a helper function to inherit prototypes and constructor stealing. Wow, that sounds complex...well yes it is - here's my implementation and test for example:
// Prototypal Inheritance
Object.prototype.inherit = function(p) {
NewObj = function(){};
NewObj.prototype = p;
return new NewObj();
};
// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
var prototype = Object.inherit(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
};
function SubType(name, age) {
Parent.call(this, name);
this.age = age;
};
inheritPrototype(SubType, Parent);
SubType.prototype.getAge = function() {
return this.age;
};
I have a test for this code:
describe 'Parisitic Combination Inheritance'
it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
sub = new SubType("Nicholas Zakas", 29)
sub.toString().should.match /.*Nicholas Zakas/
sub.getAge().should.eql 29
charlie = new SubType("Charlie Brown", 69)
charlie.arr.should.eql([1,2,3])
charlie.arr.push(999)
charlie.arr.should.eql([1,2,3,999])
sub.arr.should.eql([1,2,3])
sub.should.be_an_instance_of SubType
charlie.should.be_an_instance_of SubType
(sub instanceof SubType).should.eql true
(sub instanceof Parent).should.eql true
end
end
And of course, if you're paying attention to my literals you see: Nicholas Zakas, the guy I got this from ;) The big wins for this one: instanceof works (big deal some say and I kind of agree); instances don't share state on reference types like arrays (a biggie!); parent constructor only called once (a biggie!).
BTW, I have examples of most of the popular inheritance patterns here: My TDD JS Examples
I'd argue that the language itself steers people into the classical mindset with it's choice of "new" as a keyword, and by introducing concepts like "constructors" in the language specification. In a way this is limiting - imagine the change in mindset if instead we had a clone keyword, and the concept of traits ala SELF.
When I was writing my first scripts, it was cool and handy to have such a simple language.
But today you do not just want to toggle a buttoncolor, you want to build complex applications in JavaScript. Others might like to use your popular application and would love to see s community providing plugins.
Now, this is much easier to realize with OOP - especially because a lot of programmers a familiar with OOP concepts.
One reason may be that your server side is likely to be OO (ASP.NET, Java, etc.), so it's just easier to think in the same paradigm on the client. Not necessarily better, but easier.

What lessons can be learned from the prototype model in javascript?

The question is from a language design perspective.
I should explain a little about the situation. I am working on a javascript variant which does not support prototypes, however it is overdue a decent type system (most importantly support for instanceof). The ecmascript spec is not important, so i have the freedom to implement something different and better suited.
In the variant:-
You do not declare constructors with function foo(), rather constructors are declared in template files, which means constructors exist in a namespace (detirmined by the path of the file)
Currently all inheritance of behaviour is done by applying templates which means all shared functions are copied to each individual object (there are no prototypes afterall).
Never having been a web developer, this puts me in the slightly bizarre position of never having used prototypes in anger. Though this hasn't stopped me having opinions on them.
My principal issues with the prototype model as i understand it are
unnecessary littering of object namespace, obj.prototype, obj.constructor (is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?)
ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.
So to get around these my idea is to have a special operator constructorsof. Basically the principal is that each object has a list of constructors, which occasionally you will want access to.
var x = new com.acme.X();
com.acme.Y(x,[]); // apply y
(constructorsof x) // [com.acme.Y,com.acme.X,Object];
x instanceof com.acme.X; // true
x instanceof com.acme.Y; // true
All feedback appreciated, I appreciate it maybe difficult to appreciate my POV as there is a lot i am trying to convey, but its an important decision and an expert opinion could be invaluable.
anything that can improve my understanding of the prototype model, the good and the bad.
thoughts on my proposal
thanks,
mike
edit: proposal hopefully makes sense now.
Steve Yegge has written a good technical article about the prototype model.
I don't think your issues with the prototype model are valid:
unnecessary littering of object namespace, obj.prototype, obj.constructor
prototype is a property of the contructor function, not the object instance. Also, the problem isn't as bad as it sounds because of the [[DontEnum]] attribute, which unfortunately can't be set programatically. Some of the perceived problems would go away if you could.
is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?
There's no problem with using objects as maps as long as the keys are strings and you check hasOwnProperty().
ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
I don't see where the big implementation headache in implementning the prototype chain lies. In fact, I consider prototypical inheritance conceptually simpler than class-based inheritance, which doesn't offer any benefits in languages with late-binding.
people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.
People who only know class-based oo languages like Java and C++ don't understand JavaScript's inheritance system, news at 11.
In addition to MarkusQ's suggestions, you might also want to check out Io.
It might just be easier to try a few things with practical code. Create the language with one simple syntax, whatever that is, and implement something in that language. Then, after a few iterations of refactoring, identify the features that are obstacles to reading and writing the code. Add, alter or remove what you need to improve the language. Do this a few times.
Be sure your test-code really exercises all parts of your language, even with some bits that really try to break it. Try to do everything wrong in your tests (as well as everything right)
Reading up on "self", the language that pioneered the prototype model, will probably help you more than just thinking of it in terms of javascript (especially since you seem to associate that, as many do, with "web programming"). A few links to get you started:
http://selflanguage.org/
http://www.self-support.com/
Remember, those who fail to learn history are doomed to reimplement it.

Categories