Skip to content

Instantly share code, notes, and snippets.

@dd3141592
Last active January 25, 2016 18:12
Show Gist options
  • Save dd3141592/fa4e86b8c97a34890df8 to your computer and use it in GitHub Desktop.
Save dd3141592/fa4e86b8c97a34890df8 to your computer and use it in GitHub Desktop.
crib notes and some examples from "JavaScript Patterns" by Stoyan Stefanov //Chapter 5 Object Creation Patterns
<!DOCTYPE html>
<html>
<head>
<meta name="CH 5 Object Creation Patterns" content="Javascript Patterns">
<meta charset="utf-8">
<title>JS Bin</title>
</headJavascript patterns
<body>
Javascript Patterns, by Stoyan Stefanov (O'Reilly). Copyright 2010 Yahoo!, Inc., 9780596806750.
<script id="jsbin-javascript">
//My crib notes from "JavaScript Patterns" by Stoyan Stefanov
//Chapter 5 Object Creation Patterns
//includes some examples too
//you will need to buy the book - these notes are sketchy and for review & reference only
"use strict";
//Namespace pattern
//namespacing function
// if a namespace exists it won't be recreated
// will return a reference to a module to a local var
// will handle long namespaces
//example
var myApp = myApp || {};
myApp.namespace = function(name){
var names = name.split("."),
parent = myApp;
if(names[0] === "myApp"){
names = names.slice(1);
}
var len = names.length;
for(var i = 0; i < len; i++){
if(typeof parent[names[i]] === "undefined") {
parent[names[i]] = {};
}
parent = parent[names[i]];
}
return parent;
};
//Declaring dependencies
//benefits include -easy, faster, clearer, minification - will now minify name modules
//example
function test(){
var modules = myApp.modules;
}
//Private properties and methods
//example - create a private property with a constructor
// and a public accessor method for the property
var myObj = (function example(){
var name = "mr. big";
return{
getName : function(){ return name;}
};
})();
console.log(myObj.getName());
//beware returning reference to private object
//example
var myObj = (function example(){
var name = { salutation: "mr. big",
firstName: "bill",
lastName: "big"} ;
return{
getName : function(){ return name;}
};
})();
console.log(myObj.getName().firstName);
//use POLA (principle of least authority) to take care of this loophole
var myObj1 = (function example(){
var name = { salutation: "mr. big",
firstName: "bill",
lastName: "big"} ;
return{
getName : function(){
return {
lastName: name.lastName,
salutation: name.salutation
};
}};
})();
console.log(myObj1.getName().salutation);
console.log(myObj1.getName().firstName);
//Or
var myObj2 = (function example(){
var name = { salutation: "mr. big",
firstName: "bill",
lastName: "big"} ;
return{
getSalutation : function(){
return name.salutation;
},
getlastName : function(){
return name.lastName;
}
};
})();
console.log(myObj2.getSalutation());
console.log(myObj2.getlastName());
//prototypes and privacy
//private members in constructors and also object literals
//common parts to prototype property of constructor
//example:
function Gadget(str){
//private member
var name = str;
//public function
if(!( this instanceof Gadget)){
console.log("oh oh");
return new Gadget(str);
}
this.getName = function(){
return name;
};
}
Gadget.prototype = (function(){
//private member
var browser = "mobile webkit";
//public prototype members
return {
getBrowser: function(){
return browser;
}
};
})();
var toy = new Gadget("ipod");
console.log(toy.getName());
console.log(toy.getBrowser());
var phone = new Gadget("iphone 6");
console.log(phone.getName());
console.log(phone.getBrowser());
//question - what happens if we forget the new keyword?
var badtoy = Gadget("drone");
console.log(badtoy.getName());
console.log(badtoy.getBrowser());
//revealing private functions as public methods
var myObj = (function (){
var temp = 1,
logMe = function(str){
console.log(str);
};
return {
logMe : logMe
};
})();
myObj.logMe("this is revelation pattern");
//module pattern
//use namespace function and revelation pattern
myApp.namespace("myApp.utilities.array");
myApp.utilities.array = (function (){
var temp = 1,
logMe = function(str){
console.log(str);
};
return {
logMe : logMe
};
})();
myApp.utilities.array.logMe("this is the revealing module pattern");
//Sandbox pattern
//avoid global like myApp, long namespace names etc.
//one global contructor function only
// use this to construct objects and returns a callback
//Global constructor
//example
//new Sandbox(box);
//where box is like the myApp object - has all the functionality to make
//code work
//use the new pattern - so we can eliminate it
//also pass in a configuration object with all the required modules etc.
//example -
//Sandbox(['ajax', 'event'], function(box){});
//example - if we omit module names assume use all modules
//Sandbox(function(box){});
// can keep global namespace clear; can call Sandbox multiple times with
// different box objects
//adding modules &
//implementing the constructor
// example
//Sandbox.modules = {};
//Sandbox.modules.dom = function(box){ box.getElement = function(){};
// box.getStyle = function(){}; box.foo = "bar";
//}; etc...
// implementation
//example
// function Sandbox(){
// var array = Array.prototype.slice.call(arguments),
// callback = array.pop();
// modules = ( array[0] && (typeof array[0] === "string")) ?
// array : array[0],
// i;
// if(!(this instanceof Sandbox){
// return new Sandox(modules,callback);
// }
// check to see if no modules specified or "*" - means use all
// in this case add all modules to this object
// if(!modules || modules === "*"){
// modules = [];
// for(i in Sandbox.modules){
// if(Sandbox.modules.hasOwnProperty[i])
// modules.push(i);
//}
//}
// initialize modules
// for(i = 0 ; i < modules.length; i++){ //Sandbox.modules[module[i]](this); }
// call the call back
// callback(this);
//}
// add any prototype properties as needed
// example
// Sandbox.prototype = { name: "", version: 2, getName: function(){return this.name}};
//static members - i.e.available to all instances and called by the
// object name
//example of public static methods
var Gadget = function(){
};
// public static method
Gadget.isCool = function(){
console.log("yes!");
};
//public prototype method
Gadget.prototype.setPrice = function(price){
this.price = price;
};
var iphone = new Gadget();
Gadget.isCool();
//can't call with instance
//iphone.isCool();
//to have static work with instance too
Gadget.prototype.isCool = Gadget.isCool;
iphone.isCool();
//work differently if called by instance vs statically
var Gadget = function (price){
this.price = price;
};
Gadget.isCool = function(){
if(this instanceof Gadget){
console.log("yes! and it's price is:" + this.price );
} else {
console.log("yes!");
}
};
Gadget.prototype.isCool = Gadget.isCool;
var iphone6 = new Gadget(700);
Gadget.isCool();
iphone6.isCool();
//private static methods
var Gadget = (function(){
var count = 0;
return function(){
count++;
console.log(count);
}
})();
var g = new Gadget();
var h = new Gadget()
//create a privileged method to return the static private property
// like getMyId()
var Gadget = (function(){
var count = 0,
newGadget;
newGadget = function(){
count++;
this.countId = count;
};
newGadget.prototype.getMyId = function(){
return "my id: " + this.countId + " out of " + count;
};
return newGadget;
})();
var g1 = new Gadget();
var h1 = new Gadget()
console.log(h1.getMyId());
console.log(g1.getMyId());
//Object constants
</script>
<script id="jsbin-source-javascript" type="text/javascript">//My crib notes from "JavaScript Patterns" by Stoyan Stefanov
//Chapter 5 Object Creation Patterns
//includes some examples too
//you will need to buy the book - these notes are sketchy and for review & reference only
"use strict";
//Namespace pattern
//namespacing function
// if a namespace exists it won't be recreated
// will return a reference to a module to a local var
// will handle long namespaces
//example
var myApp = myApp || {};
myApp.namespace = function(name){
var names = name.split("."),
parent = myApp;
if(names[0] === "myApp"){
names = names.slice(1);
}
var len = names.length;
for(var i = 0; i < len; i++){
if(typeof parent[names[i]] === "undefined") {
parent[names[i]] = {};
}
parent = parent[names[i]];
}
return parent;
};
//Declaring dependencies
//benefits include -easy, faster, clearer, minification - will now minify name modules
//example
function test(){
var modules = myApp.modules;
}
//Private properties and methods
//example - create a private property with a constructor
// and a public accessor method for the property
var myObj = (function example(){
var name = "mr. big";
return{
getName : function(){ return name;}
};
})();
console.log(myObj.getName());
//beware returning reference to private object
//example
var myObj = (function example(){
var name = { salutation: "mr. big",
firstName: "bill",
lastName: "big"} ;
return{
getName : function(){ return name;}
};
})();
console.log(myObj.getName().firstName);
//use POLA (principle of least authority) to take care of this loophole
var myObj1 = (function example(){
var name = { salutation: "mr. big",
firstName: "bill",
lastName: "big"} ;
return{
getName : function(){
return {
lastName: name.lastName,
salutation: name.salutation
};
}};
})();
console.log(myObj1.getName().salutation);
console.log(myObj1.getName().firstName);
//Or
var myObj2 = (function example(){
var name = { salutation: "mr. big",
firstName: "bill",
lastName: "big"} ;
return{
getSalutation : function(){
return name.salutation;
},
getlastName : function(){
return name.lastName;
}
};
})();
console.log(myObj2.getSalutation());
console.log(myObj2.getlastName());
//prototypes and privacy
//private members in constructors and also object literals
//common parts to prototype property of constructor
//example:
function Gadget(str){
//private member
var name = str;
//public function
if(!( this instanceof Gadget)){
console.log("oh oh");
return new Gadget(str);
}
this.getName = function(){
return name;
};
}
Gadget.prototype = (function(){
//private member
var browser = "mobile webkit";
//public prototype members
return {
getBrowser: function(){
return browser;
}
};
})();
var toy = new Gadget("ipod");
console.log(toy.getName());
console.log(toy.getBrowser());
var phone = new Gadget("iphone 6");
console.log(phone.getName());
console.log(phone.getBrowser());
//question - what happens if we forget the new keyword?
var badtoy = Gadget("drone");
console.log(badtoy.getName());
console.log(badtoy.getBrowser());
//revealing private functions as public methods
var myObj = (function (){
var temp = 1,
logMe = function(str){
console.log(str);
};
return {
logMe : logMe
};
})();
myObj.logMe("this is revelation pattern");
//module pattern
//use namespace function and revelation pattern
myApp.namespace("myApp.utilities.array");
myApp.utilities.array = (function (){
var temp = 1,
logMe = function(str){
console.log(str);
};
return {
logMe : logMe
};
})();
myApp.utilities.array.logMe("this is the revealing module pattern");
//Sandbox pattern
//avoid global like myApp, long namespace names etc.
//one global contructor function only
// use this to construct objects and returns a callback
//Global constructor
//example
//new Sandbox(box);
//where box is like the myApp object - has all the functionality to make
//code work
//use the new pattern - so we can eliminate it
//also pass in a configuration object with all the required modules etc.
//example -
//Sandbox(['ajax', 'event'], function(box){});
//example - if we omit module names assume use all modules
//Sandbox(function(box){});
// can keep global namespace clear; can call Sandbox multiple times with
// different box objects
//adding modules &
//implementing the constructor
// example
//Sandbox.modules = {};
//Sandbox.modules.dom = function(box){ box.getElement = function(){};
// box.getStyle = function(){}; box.foo = "bar";
//}; etc...
// implementation
//example
// function Sandbox(){
// var array = Array.prototype.slice.call(arguments),
// callback = array.pop();
// modules = ( array[0] && (typeof array[0] === "string")) ?
// array : array[0],
// i;
// if(!(this instanceof Sandbox){
// return new Sandox(modules,callback);
// }
// check to see if no modules specified or "*" - means use all
// in this case add all modules to this object
// if(!modules || modules === "*"){
// modules = [];
// for(i in Sandbox.modules){
// if(Sandbox.modules.hasOwnProperty[i])
// modules.push(i);
//}
//}
// initialize modules
// for(i = 0 ; i < modules.length; i++){ //Sandbox.modules[module[i]](this); }
// call the call back
// callback(this);
//}
// add any prototype properties as needed
// example
// Sandbox.prototype = { name: "", version: 2, getName: function(){return this.name}};
//static members - i.e.available to all instances and called by the
// object name
//example of public static methods
var Gadget = function(){
};
// public static method
Gadget.isCool = function(){
console.log("yes!");
};
//public prototype method
Gadget.prototype.setPrice = function(price){
this.price = price;
};
var iphone = new Gadget();
Gadget.isCool();
//can't call with instance
//iphone.isCool();
//to have static work with instance too
Gadget.prototype.isCool = Gadget.isCool;
iphone.isCool();
//work differently if called by instance vs statically
var Gadget = function (price){
this.price = price;
};
Gadget.isCool = function(){
if(this instanceof Gadget){
console.log("yes! and it's price is:" + this.price );
} else {
console.log("yes!");
}
};
Gadget.prototype.isCool = Gadget.isCool;
var iphone6 = new Gadget(700);
Gadget.isCool();
iphone6.isCool();
//private static methods
var Gadget = (function(){
var count = 0;
return function(){
count++;
console.log(count);
}
})();
var g = new Gadget();
var h = new Gadget()
//create a privileged method to return the static private property
// like getMyId()
var Gadget = (function(){
var count = 0,
newGadget;
newGadget = function(){
count++;
this.countId = count;
};
newGadget.prototype.getMyId = function(){
return "my id: " + this.countId + " out of " + count;
};
return newGadget;
})();
var g1 = new Gadget();
var h1 = new Gadget()
console.log(h1.getMyId());
console.log(g1.getMyId());
//Object constants
</script></body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment