To ease the pain, many developers started using object literals and naming conventions to try and avoid name clashes, but this wasn't so great. Others were more clever and leveraged JavaScript closures with IIFEs (we discussed those in Chapter 3, Improving TodoIt with Classes and Interfaces; IIFEs are anonymous, immediately invoked, function expressions) to encapsulate/isolate parts of their code and expose only the properties and functions that they wanted to.
This approach became known as the Revealing Module pattern (http://jargon.js.org/_glossary/REVEALING_MODULE_PATTERN.md). A popular example of this was jQuery, whose plugin system used this approach.
Here's a concrete example of a module using this pattern:
var myBooks = (function() { var collection = [ { name: "Lord of the rings", author: "JRR Tolkien", rating: 10 }, { name: "1984", author: "George Orwell", rating: 9 } ]; function getCollection() { return collection; } function favoriteBook() { return collection[0]; } function sortBooks() { // no-op } function addBook(book) { collection.push(book); sortBooks(); } return { books: getCollection(), addBook: addBook, favoriteBook: favoriteBook() } })(); // immediately invoked
myBooks.addBook({name: "foo", author: "bar"}); console.log(myBooks.books); console.log("Favorite: ", myBooks.favoriteBook);
In this example, the only global variable is myBooks. In the return statement of its associated function, we define the public API of our module. This allows us to keep some parts private, such as the sortBooks function.
IIFEs and the Revealing Module pattern were only the first steps toward better code organization and other variations of module definitions were devised over time. Unfortunately, they only solved part of the modularization puzzle. They only helped with the isolation/encapsulation of code, not dealing with dependencies.