Person.js
/** * This example make use of Requirejs to provide a clean and simple-to-Split JavaScript class definitions * into SE Parate files and avoid global namespace pollution. http://requirejs.org/* * We start by defining the definition within the Require block inside a function; This means, any * new variables/methods is not being added to the global namespace; Requirejs simply requires us to return * A single value (Function/object) which represents this definition. In our case, we'll be returning * the Class ' function. */define (function () {//forces the JavaScript engine into strict MODE:HTTP://TINYURL.COM/2DONDLH ' use strict '; /** * This was 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 CA Pital letter. This informs users, 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 the callee have invoked our Class ' constructor functi On//With the ' new ' keyword-failure to does this would result in the ' this ' keyword referring//to the CAL Lee ' s scope (typically the window global) which would 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 is called as a function."); }//Here we create a member property (field) for the person ' s name; setting its value//What's the one supplied to the Constructor. Although we don ' t has to define//properties ahead of time (they can easily is added at runtime as all object/f Unctions//In JavaScript is dynamic) I believe it makes your code easier to follow If you list your//classes intentions up front (eg:in the Constructor function). THIS.name = name; Here we are defining a private member. As there is no ' private ' keyword in JavaScript//There is no-on-US-to-hide this data (without resorting to Elegant hacks); instead//We choose to use a naming convention where a leading underscore indicates a property//is Privat E and should not being 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. */person.retirement_age = 60; /** * Public Static methods is defined in the same; Here's a static constructor for we person class * which also sets the person's age. */person.create = function (name, age) {var result = new person (name); Result.setage (age); return result; }; /** * Any functions not Added to the person reference won ' t is visible, or accessible outside of * This file (closure); However, these methods and functions don ' t belong to the person class either * and is static as a result. */function Formatnameandage (person) {//Note which ' this ' does not refer to the person object from inside this Method. if (person._age = =-1) {return "We don t know how old" + Person.name + "is!";} Return (Person.name + ", is" + Person._age + "years old and" + ((Person.canretire ())? " Can ":" Can ' t ") +" retire "); }; /** * The prototype is a special type of Object which be used as a blueprint for all instances * of a given Cl the; By defining functions and properties on the prototype we reduce memory * overhead. We can also achieve inheritance by pointing one classes ' prototype @ Another, for * example, if we introduced a BANKM Anager 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's of the opinion that favouring composition * over inheritance WI ll make your code easier to read and re-use. */Person.prototype = {/** * whenever you replace a Object ' s prototype, you need to repoint * the base Constructor back at the original Constructor Function, * otherwise ' instanceof ' calls'll fail. */Constructor:person,/** * All methods added to a Class ' prototype is public (visible); They is able to * access the properties and methods of the WHO class via the ' this ' keyword. Note that * Unlike ActionScript, usage of the "This" keyword is required, failure to use it would * result In the JavaScript engine trying to resolve the definition on the global object. */Greet:function () {//NOTE We have the "this" keyword. Return "Hello," + this.name; },/** * Even tho the ' _age ' property is accessible; It still makes a lot of sense to provide * mutator methods (getters/setters) which do up the public API of a C Lass-here we * validate the supplied value; Something you can ' t be 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 ' The It can operate on the this instance. Return Formatnameandage (this); } }; As mentioned up top, Requirejs needs us to return a value-in this files case, we'll return//a reference to the constructor function. return person;});
Use:
Require ([' site '],function (person) { var jonny = new Person ("Jonny"); Jonny.setage (); Console.log (Jonny.tostring ()); });
Requirejs AMD Module Load Example