Object Literals
First lets take a look the most straight forward pattern (I know it's not really a pattern but its still a way some developers use to organize their code): the object literal. In the object literal "this" points to the object's properties, in fact, you have to use "this" to refer to any of the objects. One important thing to note here is that nested functions DO NOT have access to the objects "this" scope. Look at the sayHello function in the code below, notice that there is an inner "helper" function. Trying to access "this" within it would refer to the window object and not the person object. In order to provide access to "this" a common workaround is to create another variable that points to "this". Here I'll call it "self".
//this and objects var person = { firstName: "Ryan", lastName: "Anklam", getFullName: function() { //inside an object we need to point to this to access its properties var firstName = "Yoko"; //this var is local to the function so, but 'this' still outputs Ryan return this.firstName + ' ' + this.lastName; }, sayHello : function(){ var self= this; var inner = function(){ //this inner function doesn't have privlaged access to the object's vars. "this" in here actually refers to the "window" object return self.getFullName() + " says hello"; }; return inner(); } };
http://jsfiddle.net/bittersweetryan/wewY4/
IIFE's / Modules
In the module pattern things get interesting since the context of "this" is really the "window" context, however, one of the common ways to provide public members to an IIFE is to return an object with public functions. As we discussed before there is a "this" scope within the object literal. Since everything is nicely encapsulated in the IIFE the object can directly access it's parent function's variables.
var person = (function(){ var firstName = "Gregg"; var lastName = "Jennings"; return{ getFirstName : function(){ return firstName + ' ' + lastName; }, sayHello : function(){ return this.getFirstName() + " says hello"; } }; })();
One interesting twist that I first saw on Ben Nadal's blog post "Decoding Morse Code With JavaScript" was to use the call() method when invoking the IIFE and passing in a new object for the context of this. What I really like about this approach is that we don't have to return a new object literal, we can just return "this" to provide public access to methods that are assigned to the "this" scope.
var person = (function(){ //these are private still var firstName = "Aaron"; var lastName = "Rodgers"; //this will be made public by returning this (see the end of the person function to see where this is coming from this.getFirstName = function(){ return firstName + ' ' + lastName; }; this.sayHello = function(){ return this.getFirstName() + " says hello"; }; return this; }).call({}); //sweet! we can set this in an IIFE by passing in a blank object literal using the call method
http://jsfiddle.net/bittersweetryan/qzkzy/
Constructor Functions
When dealing with Constructor functions you should be very careful. The "this" context will ONLY exist after a new instance of the constructor is created using the new keyword. Once the new keyword is used to create a new object only functions that are assigned to the "this" context will be made public. In the example below the sayHello function will only be available after the new keyword is used to create a new instance of the function.
//this and a prototype function Person(){ var firstName = "Chales"; var lastName = "Woodson"; //private within Person object function getFullName(){ return firstName + ' ' + lastName; }; //public function that returns the firstName and lastName this.sayHello = function(){ return getFullName() + " says hi"; } }; //this will throw an error since it tries to access a property in the this scope which isn't defined without using new //console.log(Person.sayHello()); var newPerson = new Person(); console.log(newPerson.sayHello());
http://jsfiddle.net/bittersweetryan/45ceQ/