Skip to content

Instantly share code, notes, and snippets.

@jackmakesthings
Created June 5, 2014 18:11
Show Gist options
  • Save jackmakesthings/7e70f05907f583149e91 to your computer and use it in GitHub Desktop.
Save jackmakesthings/7e70f05907f583149e91 to your computer and use it in GitHub Desktop.
Module patterns and stuff, via Addy Osmani's book on js patterns - http://addyosmani.com/resources/essentialjsdesignpatterns/book/
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
var basketModule = (function () {
// privates
var basket = [];
function doSomethingPrivate() {
//...
}
function doSomethingElsePrivate() {
//...
}
// Return an object exposed to the public
return {
// Add items to our basket
addItem: function( values ) {
basket.push(values);
},
// Get the count of items in the basket
getItemCount: function () {
return basket.length;
},
// Public alias to a private function
doSomething: doSomethingPrivate,
// Get the total value of items in the basket
getTotal: function () {
var q = this.getItemCount(),
p = 0;
while (q--) {
p += basket[q].price;
}
return p;
}
};
})();
// basketModule returns an object with a public API we can use
basketModule.addItem({
item: "bread",
price: 0.5
});
basketModule.addItem({
item: "butter",
price: 0.3
});
// Outputs: 2
console.log( basketModule.getItemCount() );
// Outputs: 0.8
console.log( basketModule.getTotal() );
// However, the following will not work:
// Outputs: undefined
// This is because the basket itself is not exposed as a part of our
// the public API
console.log( basketModule.basket );
// This also won't work as it only exists within the scope of our
// basketModule closure, but not the returned public object
console.log( basket );
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
var vehiclePrototype = {
init: function ( carModel ) {
this.model = carModel;
},
getModel: function () {
console.log( "The model of this vehicle is.." + this.model);
}
};
function vehicle( model ) {
function F() {};
F.prototype = vehiclePrototype;
var f = new F();
f.init( model );
return f;
}
var car = vehicle( "Ford Escort" );
car.getModel();
/*
* "Highly configurable" mutable plugin boilerplate
* Author: @markdalgleish
* Further changes, comments: @addyosmani
* Licensed under the MIT license
*/
// Note that with this pattern, as per Alex Sexton's, the plugin logic
// hasn't been nested in a jQuery plugin. Instead, we just use
// jQuery for its instantiation.
;(function( $, window, document, undefined ){
// our plugin constructor
var Plugin = function( elem, options ){
this.elem = elem;
this.$elem = $(elem);
this.options = options;
// This next line takes advantage of HTML5 data attributes
// to support customization of the plugin on a per-element
// basis. For example,
// <div class="item" data-plugin-options="{'message':'Goodbye World!'}"></div>
this.metadata = this.$elem.data( "plugin-options" );
};
// the plugin prototype
Plugin.prototype = {
defaults: {
message: "Hello world!"
},
init: function() {
// Introduce defaults that can be extended either
// globally or using an object literal.
this.config = $.extend( {}, this.defaults, this.options,
this.metadata );
// Sample usage:
// Set the message per instance:
// $( "#elem" ).plugin( { message: "Goodbye World!"} );
// or
// var p = new Plugin( document.getElementById( "elem" ),
// { message: "Goodbye World!"}).init()
// or, set the global default message:
// Plugin.defaults.message = "Goodbye World!"
this.sampleMethod();
return this;
},
sampleMethod: function() {
// e.g. show the currently configured message
// console.log(this.config.message);
}
}
Plugin.defaults = Plugin.prototype.defaults;
$.fn.plugin = function( options ) {
return this.each(function() {
new Plugin( this, options ).init();
});
};
// optional: window.Plugin = Plugin;
})( jQuery, window , document );
/*!
* jQuery "best options" plugin boilerplate
* Author: @cowboy
* Further changes: @addyosmani
* Licensed under the MIT license
*/
;(function ( $, window, document, undefined ) {
$.fn.pluginName = function ( options ) {
// Here's a best practice for overriding "defaults"
// with specified options. Note how, rather than a
// regular defaults object being passed as the second
// parameter, we instead refer to $.fn.pluginName.options
// explicitly, merging it with the options passed directly
// to the plugin. This allows us to override options both
// globally and on a per-call level.
options = $.extend( {}, $.fn.pluginName.options, options );
return this.each(function () {
var elem = $(this);
});
};
// Globally overriding options
// Here are our publicly accessible default plugin options
// that are available in case the user doesn't pass in all
// of the values expected. The user is given a default
// experience but can also override the values as necessary.
// e.g. $fn.pluginName.key ="otherval";
$.fn.pluginName.options = {
key: "value",
myMethod: function ( elem, param ) {
}
};
})( jQuery, window, document );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment