32

A lot of web frameworks have a MVC-style layout to code and approaching problems. What are some good similar paradigms for JavaScript? I'm already using a framework (jQuery) and unobtrusive js, but that still doesn't address the problem I run into when I have more complex web apps that require a lot of javascript, I tend to just end up with a bunch of functions in a single, or possibly a few files. What's a better way to approach this?

GSto
  • 8,531
  • 7
  • 39
  • 59
  • 2
    ["JavaScript Patterns" by Stoyan Stefanov](http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) would be a good place to start. – c69 Apr 07 '12 at 16:10
  • I got a really helpful link on this ( http://www.commented-out.com/2012/05/28/javascript-youre-doing-it-wrong/ ) in the answer to a recent question on SO ( http://stackoverflow.com/questions/15137572/do-i-always-have-to-apply-the-this-or-that-scope-to-all-object-propertie ) - you may find other answers there helpful as well. – glenatron Apr 12 '13 at 16:10
  • +1 @c69 on Stefanov's book. It goes over patterns that actually make since and are useful in the context of JavaScript, instead of just implementing Gang of Four patterns in the language. – bunglestink Apr 12 '13 at 18:16

7 Answers7

18

Namespacing: Don't forget to use objects as a pseudo-package (most frameworks do this, you should also):

var YourCompany = {};

YourCompany.util = {};

YourCompany.util.myFunction = function() { /* ...  */ }

You don't necessarily need to set it up that way, and use whatever naming conventions you prefer, but the namespacing will help you out a lot (makes it easier on refactoring search-and-replace too, when you decide to move something).

Nicole
  • 28,111
  • 12
  • 95
  • 143
12

some people don't realize that JS is fully object oriented. You can create something that works just like a class:

function Car() {
    this.publicField = "bad";
    var privateField = "good";
    var self = this;

    this.publicMethod = function() {
        alert("I can access " + this.publicField + " and " + privateField);
    }

    function privateMethod() {
        alert("I can access " + self.publicField + " and " + privateField);
    }
}

you can instantiate those classes:

var car = new Car();

and it supports inheritance:

function Vehicle() { /* define class */ }

function Truck() { /* define class */ }
Truck.prototype = new Vehicle();

and can even add methods to existing classes:

Array.prototype.remove = function() {
}

If you'd like to learn more about JavaScript's OO support, I highly recommend the Rhino book.

Brad Cupit
  • 661
  • 6
  • 16
  • 2
    you don't need classes to be fully object oriented – Javier Dec 08 '10 at 03:46
  • 4
    Also it's not *really* classes. It's prototype-based, which is in direct opposition to class-based languages. See http://en.wikipedia.org/wiki/Prototype-based_programming – Nicole Dec 08 '10 at 04:53
  • @BradCupit adding methods to the standard objects like Array is an extrememly bad thing . – Subhra Jul 22 '12 at 14:05
  • @Subhra Oh I disagree. Can it be done poorly? Certainly, but if you're adding a method that arguably should be part of the standard then it's a very nice feature. – Brad Cupit Nov 02 '12 at 18:47
  • When are we going to start saying you can write something that works better than a class? – Erik Reppen Feb 24 '13 at 06:30
6

This link describes, better than I could, a sane way to architecture a medium-to-large Javascript application. Among other things, this involves:

  • Splitting code into modules, using the module pattern
  • Letting the modules declare their dependencies and load them asynchronously via a tool like RequireJS
  • Namespacing the global objects you define
  • Abstracting away the DOM manipulation library (this only makes sense for large enough projects)
  • Following (some variation of) the MVC pattern, leaving to models the role of data persistence and AJAX calls, to controller the role of managing events and to views the role of DOM and style manipulations
  • Minimizing the communication through independent modules, by means of some core that dispatches messages
  • Designing a mechanism that restarts module as soon as they throw an exception. As a consequence, designing modules so that their restart does not have unexpected consequences (like drawing some UI element twice)
  • Combine reusable parts of the UI into widgets
Andrea
  • 5,355
  • 4
  • 31
  • 36
3

I'd recommend using namespacing and then a file structure that mirrors the namespace. For example, using Brad's answer, I'd have Truck.js, Car.js and Vehicle.js. This should give you a codebase that is easier to maintain, organise and unit test. However, you should have some kind of build process which concatenates and minfies your multiple JS files ready for production.

With an organised codebase of prototypal objects you should be in a position to implement most design patterns. There are also some good books on this subject. This presentation by Nicholas Zackas is also useful to get some insight in how to build good Javascript apps.

Also, in Javascript, I think its also important to distinguish between patterns and techniques. You need to be familiar with various commonly used techniques which JS natively lacks, such as namespacing. But these are techniques not patterns; techniques which make it easier to build patterns such as those defined by the Gang of Four.

Sorry this such a brief summary. But I'd strongly recommend the resources I mentioned to get greater insight.

Phil Mander
  • 321
  • 2
  • 6
2

There are some recently added new articles that focus on implementing JavaScript Design Patterns and some of the Gang-of-Four Design Patterns using JavaScript:

  1. JavaScript Design Patterns: Chain of Responsibility (Last updated February 20, 2012) - Although this article obviously focuses on Chain of Responsibility, it has links to many of the other GoF patterns implemented in JavaScript.
  2. Essential JavaScript & jQuery Design Patterns (Last updated April 30, 2012)
Sean Mickey
  • 301
  • 1
  • 6
0

Using jQuery is a great start. JavaScript in a browser augments the frontend, there isn't a MVC "pattern" or anything to follow. There are some "best practices" that help keep the code clean.

  • Separate functions for separate things. Bindings in one, actions in another. Make use of this as well as classes for actions.
  • Remember that JavaScript allows a great deal of flexibility, passing closures around as they are created can help simplify your bindings and lighten the code.
  • Shield from the global scope, only expose what is necessary.
  • Use JSLint to keep your code up to standards.

For server side / non-browser JavaScript (like Node.js) there are several great frameworks for building off of. It might be worth while browsing through the source to see if you pick up on any thing.

I moved this to a more in-depth entry for the interested.

Josh K
  • 23,019
  • 10
  • 65
  • 100
  • [JS.Class](http://jsclass.jcoglan.com/) is also a great start for developing better class-based JS. – Nicole Dec 07 '10 at 22:01
  • @Renesis: better than what? – Javier Dec 08 '10 at 03:45
  • @Javier Better than plain JS - using a single level prototype. JS.Class gives you the ability to easily create classes with inheritance (prototype inheritance only supports method overwriting. JS.class gives you real inheritance, where you can call the super method) and mixins. Did you check out the link? – Nicole Dec 08 '10 at 04:50
  • I do not agree with this answer. As the size of the application grows, certain patterns definitely help manage the complexity, and MVC is one of those (but is not enough on its own) – Andrea Dec 04 '11 at 12:44
  • 1
    @NickC Or you could learn JavaScript before trying to make it work like some other language that you know. – Erik Reppen Feb 24 '13 at 06:32
  • @NickC Sorry. That wasn't really meant to offend but I can see how it would and that it did. Apologies. I've just waded through a lot of code that went the class route and did uber-inheritance on everything (like EXTjs for instance), making it a PITA to read. Give JS's approach to OOP a fair shake if you haven't yet. You can do inheritance but compositing is a better fit, typically. – Erik Reppen Feb 25 '13 at 18:09
  • @ErikReppen Thanks, and sorry, I may have been overly sensitive. I am quite experienced with JS, but your comment is fair. Having done quite a bit with Plain Old JS, I look for utilities that abstract the common motions, however, like everything it can be abused. The fact that it is created to act like other languages may encourage that abuse. I've seen organizations with large teams and lots of code go the class/module route, but I admit not without producing your readability complaint. And I can agree that composition is a good thing; would love to see that as an answer on this question. – Nicole Feb 26 '13 at 00:29
-2

From a practical standpoint, take a good look at AngularJS and KnockoutJS. These frameworks solve real problems that you encounter when building JS heavy applications. Angular is a more "all inclusive" solution with many advanced freatures, whereas Knockout only tackles the problem of realtime UI updating. Both are very nice, and when used correctly can help structure your application in an MVC style while actually being productive. There are a plethora of other "JavaScript MVC libraries" out there, but frankly, most of them just try to shoehorn an MVC pattern without actually solving any real world problems.

As commented, JavaScript Patterns is a very useful book that takes a lower level look at what patterns are actually useful in the language.

bunglestink
  • 2,262
  • 16
  • 26
  • how does this answer the question asked? "What are some good similar paradigms for JavaScript?" – gnat Apr 12 '13 at 18:44
  • @gnat This answers the question aksed - not the title: "I'm already using a framework (jQuery) and unobtrusive js, but that still doesn't address the problem I run into when I have more complex web apps that require a lot of javascript, I tend to just end up with a bunch of functions in a single, or possibly a few files. What's a better way to approach this?" These are libraries that provide patterns and structure well beyond basic unobtrusive jQuery usage. – bunglestink Apr 12 '13 at 18:51