Skip to content

Instantly share code, notes, and snippets.

Forked from jonnyreeves/index.html
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0x-2a/3bb45c80b7c8f9636112 to your computer and use it in GitHub Desktop.
Save 0x-2a/3bb45c80b7c8f9636112 to your computer and use it in GitHub Desktop.
JavaScript Class Structure using requireJS. The following code shows you how to create a Class definition in one JavaScript file and then import it for use in another; coming from an ActionScript 3 background this (and some of JavaScript specific traits)
<!DOCTYPE html>
<script data-main="usage" src=""></script>
<p>Check your JavaScript console for output!</p>
* This example make use of requireJS to provide a clean and simple way to split JavaScript class definitions
* into separate files and avoid global namespace pollution.
* We start by defining the definition within the require block inside a function; this means that any
* new variables / methods will not be added to the global namespace; requireJS simply requires us to return
* a single value (function / Object) which represents this definition. In our case, we will be returning
* the Class' function.
define(function () {
// Forces the JavaScript engine into strict mode:
"use strict";
* This is our classes constructor; unlike AS3 this is where we define our member properties (fields).
* To differentiate constructor functions from regular functions, by convention we start the function
* name with a capital letter. This informs users that they must invoke the Person function using
* the `new` keyword and treat it as a constructor (ie: it returns a new instance of the Class).
function Person(name) {
// This first guard ensures that the callee has invoked our Class' constructor function
// with the `new` keyword - failure to do this will result in the `this` keyword referring
// to the callee's scope (typically the window global) which will result in the following fields
// (name and _age) leaking into the global namespace and not being set on this object.
if (!(this instanceof Person)) {
throw new TypeError("Person constructor cannot be called as a function.");
// Here we create a member property (field) for the Person's name; setting its value
// what the one supplied to the Constructor. Although we don't have to define
// properties ahead of time (they can easily be added at runtime as all Object / functions
// in JavaScript are dynamic) I believe it makes your code easier to follow if you list your
// classes intentions up front (eg: in the Constructor function). = name;
// Here we are defining a private member. As there is no `private` keyword in JavaScript
// there is no way for us to hide this data (without resorting to inelegant hacks); instead
// we choose to use a naming convention where a leading underscore indicates a property
// is private and should not be relied upon as part of the Classes public API.
this._age = -1;
* Adding static properties is as simple as adding them directly to the constructor
* function directly.
* Public Static methods are defined in the same way; here's a static constructor for our Person class
* which also sets the person's age.
Person.create = function (name, age) {
var result = new Person(name);
return result;
* Any functions not added to the Person reference won't be visible, or accessible outside of
* this file (closure); however, these methods and functions don't belong to the Person class either
* and are static as a result.
function formatNameAndAge(person) {
// Note that `this` does not refer to the Person object from inside this method.
if (person._age === -1) {
return "We don't know how old " + + " is!";
return ( + ", is " + person._age + " years old and "
+ ((person.canRetire()) ? "can" : "can't") + " retire");
* The prototype is a special type of Object which is used as a the blueprint for all instances
* of a given Class; by defining functions and properties on the prototype we reduce memory
* overhead. We can also achieve inheritance by pointing one classes' prototype at another, for
* example, if we introduced a BankManager class which extended our Person class, we could write:
* `BankManager.prototype = Person.prototype`
* `BankManager.prototype.constructor = BankManager`
* However, due to the dynamic nature of JavaScript I am of the opinion that favouring composition
* over inheritance will make your code easier to read and re-use.
Person.prototype = {
* Whenever you replace an Object's Prototype, you need to repoint
* the base Constructor back at the original constructor Function,
* otherwise `instanceof` calls will fail.
constructor: Person,
* All methods added to a Class' prototype are public (visible); they are able to
* access the properties and methods of the Person class via the `this` keyword. Note that
* unlike ActionScript, usage of the `this` keyword is required, failure to use it will
* result in the JavaScript engine trying to resolve the definition on the global object.
greet: function () {
// Note we have to use the `this` keyword.
return "Hello, " +;
* Even tho the `_age` property is accessible; it still makes a lot of sense to provide
* mutator methods (getters / setters) which make up the public API of a Class - here we
* validate the supplied value; something you can't do when a field is modified directly
setAge: function (value) {
// Ensure the supplied value is numeric.
if (typeof (value) !== 'number') {
throw new TypeError(typeof (value) + " is not a number.");
// Ensure the supplied value is valid.
if (isNaN(value) || value < 0) {
throw new RangeError("Supplied value is out of range.");
this._age = value;
* This method access both a member property and a static property.
canRetire: function() {
return this._age >= Person.RETIREMENT_AGE;
* Finally we can also access 'static' functions and properties.
toString: function() {
// Note that as `formatNameAndAge` is static we must supply a reference
// to `this` so it can operate on this instance.
return formatNameAndAge(this);
// As mentioned up top, requireJS needs us to return a value - in this files case, we will return
// a reference to the constructor function.
return Person;
* Here's a simple usecase for our Person class, again we will start by using requireJS to 'define' a
* new class; however note how we pass the `require` object through to the closure as an argument, this
* allows us to retrieve other exported modules / class definitions that have been 'define'd.
define(function (require) {
"use strict";
// requireJS will ensure that the Person definition is available to use, we can now import
// it for use (think of this as your import statement in AS3).
var Person = require('Person');
// We can now invoke the constructor function to create a new instance and invoke that instance's
// methods.
var jonny = new Person("Jonny");
// We can also access any public static methods and properties attached to the Person function:
var sean = Person.create("Sean", 30);
console.log("Generally speaking, you can retire at " + Person.RETIREMENT_AGE);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment