Javascript Data-Structure Instantiation Patterns

earlier this week I learned about the many ways to instantiate a data-structure in javascript. here's what I took away, along with with some examples:

functional: a single function that instantiates an empty instance of an object that we will store data on. we will access the data with functions that we store as properties on the object - aka methods.

var dude = function(name, currentCity, food){  
  var newHacker = {};

  newHacker.name = name;
  newHacker.currentCity = currentCity;
  newHacker.favoriteFood = food;
  newHacker.eatAFood = function(){
    if (newHacker.favoriteFood){
      console.log(newHacker.name + " is totally chomping on some " + newHacker.favoriteFood + " in " + newHacker.currentCity + "!");
    }
  };
  return newHacker;
}
var Adam = dude('Adam','San Francisco','Freedom Fries');  
Adam.eatAFood()  

Adam is totally chomping on some Freedom Fries in San Francisco!

functional-shared: using a few functions that separate concerns, we can make an object that defines properties and methods to be appended to any data store that we extend to it, thereby making the code more DRY, and allowing for fewer instances of those methods upon instantiating new objects. In the previous example, every time we would instantiate a new 'dude', we would create another instance of the 'eatAFood' method. In the following example, we can have one instance in memory of the 'eatAFood' method, even if we create 250 different people.

first, we need a function to assign the properties of one object to another. this helps when we want to share common methods with objects that have other differing properties. this is a naive implementation of the _.extend method from the must-have javascript utility library, UnderscoreJS.

var extend = function(obj1, obj2) {  
  for (var a in arguments){
    for (var prop in arguments[a]){
      obj1[prop] = arguments[a][prop];
    }
  }
  return obj1;
};

now we need a border-line, tastefully sexist example of a few objects that get properties and methods from other objects on instantiation:

var peep = function(name, gender, currentCity, food){  
  var peepHacker = {};

  peepHacker.name = name;
  peepHacker.currentCity = currentCity;
  peepHacker.favoriteFood = food;
  if (gender === "Male"){
    extend(peepHacker, dudeHacker);
  } else if (gender === "Female"){
    extend(peepHacker, chickHacker);
  }
  extend(peepHacker, peopleMethods);
  return peepHacker;
};

var dudeHacker = {};  
dudeHacker.gender = 'dude';  
dudeHacker.hobby = 'wearing a hoodie'

var chickHacker = {};  
chickHacker.gender = 'chick';  
chickHacker.hobby = 'buying shoes'

var peopleMethods = {};  
peopleMethods.eatAFood = function(){  
  if (this.favoriteFood){
    console.log("This " + this.gender + " " + this.name + " is totally chewing on some " + this.favoriteFood + " in " + this.currentCity + " while " + this.hobby + "!");
  }
  return true;
};
var Adam = peep('Adam','Male','San Francisco','freedom fries');  
var KatyPerry = peep('Katy','Female','Los Angeles','carrots');  
Adam.eatAFood();  

This dude Adam is totally chewing on some freedom fries in San Francisco while wearing a hoodie!

KatyPerry.eatAFood();  

This chick Katy is totally chewing on some carrots in Los Angeles while buying shoes!

prototypal: a function that uses the Object.create() method to instantiate the new data structure. we pass it an object for data store that was defined outside of the function. We also previously defined the methods of that data store object as it's properties, and did so outside of the function.

var makePeepHacker = function(name, gender, currentCity, food, hobby){  
    var peep = Object.create(peepHacker(name, gender, currentCity, food, hobby));
    return peep;
};

var peepHacker = function(name, gender, currentCity, food, hobby){  
    var hacker = Object.create(peopleMethods);
    hacker.name = name;
    hacker.currentCity = currentCity;
    hacker.favoriteFood = food;
    hacker.gender = gender
    hacker.hobby = hobby;
    return hacker;
}
var peopleMethods = {};  
peopleMethods.isDoing = function(){  
  if (this.favoriteFood){
    console.log("This " + this.gender + " " + this.name + " is totally chewing on some " + this.favoriteFood + " in " + this.currentCity + " while " + this.hobby + "!");
  }
  return true;
};
var Chris = makePeepHacker('Chris Christie','dude','Trenton','taylor ham, egg and cheese','causing a traffic jam');  
var POTUS = makePeepHacker('Barak Obama','dude','Washington, D.C.','chili dogs','botching an epic site launch');  
Chris.isDoing();  

This dude Chris Christie is totally chewing on some taylor ham, egg and cheese in Trenton while causing a traffic jam!

POTUS.isDoing();  

This dude Barak Obama is totally chewing on some chili dogs in Washington, D.C. while botching an epic site launch!

pseudoclassical: a function that is named for the class that it creates, and assigns its storage object and data access properties to 'this'. We then define more data access methods as properties of this class's prototype. So, calling the original function will effectively instantiate as a new object with these properties.

var Peep = function(name, species, currentCity, activity, hobby){  
    this._name = name;
    this._species = species;
    this._currentCity = currentCity;
    this._activity = activity;
    this._hobby = hobby;
};

Peep.prototype.isDoing = function(){  
  console.log("This " + this._species + " " + this._name + " is totally " + this._activity + " in " + this._currentCity + " while " + this._hobby + "!");
  return true;
};

Peep.prototype.shoutName = function(){  
    console.log(this._name.toUpperCase() + "!!!!!!");
};
var Kanye = new Peep('Yeezy','monster','chi-town','spitting a new verse','improving upon his own self-worship');  
Kanye.isDoing();  

This monster Yeezy is totally spitting a new verse in chi-town while improving upon his own self-worship!

Kanye.shoutName();  

YEEZY!!!!!!