These are the slides for this presentation http://www.meetup.com/HardCoreJS/events/133346272/
The goal is to influence the thought process of developers and make them into rockstar engineers by showing how to form the habit of abstraction into one's coding.
2. Preface
• Based on personal observations
• Spanning over 15 companies
• Small companies to mostly enterprise
• Not based on comprehensive research
• Full life cycle of web development
4. Analyze
<html>
<head>
<title>
This is the title of the page
</title>
</head>
<body>
<p id="main_content">
This is my content
</p>
<ul>
<li class="first"> One
<li> Two
<ol>
<li class="first"> A
</ol>
<li>
</ul>
</body>
</html>
5. Analysis
• A document
• A tree of hierarchal nodes off of root node
• Two children nodes off of root node
• Second child node has two children nodes
• Two children nodes are siblings
6. Overview
• Ultimate goal is to write less code
• Increase reusability
• Change way of thinking
• Change way of coding
• Anticipate future code evolution
8. Before
function resolveFirstName(person) {
if (person.firstName)
return person.firstName;
else
return "First name could not be found!";
}
!
function findAge(person) {
return person.age;
}
!
function printOutName(person) {
if (cookie === "senior") {
findAge() + 20;
resolveAddress();
}
return person.lastName || "No last name was found on record!";
}
9. After
function errorMessage(descriptor) {
return ({
age : "Age could not be determined",
firstName : "First name could not be found!",
lastName : "No last name was found on record!"
})[descriptor];
}
!
function resolveDescriptor(descriptor) {
return typeof this[descriptor] !== "undefined"
? this[descriptor]
: errorMessage(descriptor);
}
!
function resolveSeniority() {
if (cookie === "senior") {
findAge() + 20;
resolveAddress();
}
}
11. Overloading
• One function serves multiple purposes
• Argument signature determines function
• Must differ by arity or data types
• Same function name
• JavaScript can only simulate overloading
12. Example
function addMethod(object, name, fn){ // addMethod - By John Resig (MIT Licensed)
var old = object[ name ];
object[ name ] = function(){
if ( fn.length == arguments.length )
return fn.apply( this, arguments );
else if ( typeof old == 'function' )
return old.apply( this, arguments );
};
}
function Users(){
addMethod(this, "find", function(){
// Find all users...
});
addMethod(this, "find", function(name){
// Find a user by name
});
addMethod(this, "find", function(first, last){
// Find a user by first and last name
});
}
13. Usage
var users = new Users();
!
users.find(); // Finds all
!
users.find("John"); // Finds users by name
!
users.find("John", "Resig"); // Finds users by first and last name
!
users.find("John", "E", "Resig"); // Does nothing
14. Events
• Usually we couple an event to a function
• Sometimes many functions to one event
• We know what happens on an event
• We should not care what happens
• Decouple handlers from events
20. Object Oriented
joe = new Person();
function Person() {
this.hi = sayHello;
}
jane = new Person();
joe.hi();
jane.hi();
function sayHello() {
alert(‘hello world!’);
}
21. Example
function Person(name) {
this.hi = sayHello;
this.name = name;
function sayHello() {
console.log('hello world from ' + this.name);
}
}
!
function init(names) {
var people = [];
for (var i = 0, count = names.length; i < count; i++) {
people.push(new Person(names[i]));
}
return people;
}
function greet(people) {
for (var i = 0, count = people.length; i < count; i++) {
people[i].hi();
}
}
greet(init(["Joe", "Jane"]));
22. Example
var Rifle = function () {
this.reload = function () {};
this.fire = function () { /* ... */ };
},
!
Cannon = function () {
this.reload = function () {};
this.fire = function () {};
};
!
var Soldier = function (gun) {
this.currentGun = gun;
this.inventory = {
guns : [ gun ]
};
this.attack = function () { this.currentGun.fire(); };
};
!
var Tank = function (gun) {
this.currentGun = gun;
this.inventory = {
guns : [ gun ]
};
this.attack = function () { this.currentGun.fire(); };
};
!
var soldier = new Soldier( new Rifle() ),
tank
= new Tank( new Cannon() );
23. Example
var Rifle = function () {
this.reload = function () {};
this.fire = function () { /* ... */ };
},
!
Cannon = function () {
this.reload = function () {};
this.fire = function () {};
};
!
var Combatant = function (gun) {
this.currentGun = gun;
this.inventory = {
guns : [ gun ]
};
this.attack = function () { this.currentGun.fire(); };
};
!
var soldier = new Combatant( new Rifle() ),
tank
= new Combatant( new Cannon() );
24. MVC
• Abstraction engrained in architecture
• Separation of concerns (SoC)
• Decouple model, view, controller
• Each component replaceable
• Any of these can be further abstracted
27. Example
function controller(model, view) {
var items = “";
!
for (var i = 0, count = model.items.length; i < count; i++) {
items += view.item.replace("{{item}}", model.items[i]);
}
}
return view.list.replace("{{items}}", items);
!
!
var view = {
item : "<li>{{item}}</li>",
list : "<ul>{{items}}</ul>"
};
!
var model = {
items : [1, 2, 3]
};
!
console.log(controller(model, view));
28. RWD / AWD
• Responsive responds to screen widths
• Adaptive adapts to devices
• Use mobile-first approach in all code
• Segment code to accommodate growth
• Use lazy loaders and module patterns
30. Thought Process
• Do not care for specifics
• Do not care who calls what
• Assume anyone can call anything
• Assume anything can contain anything
• Think interfaces not internals
31. APIs
• Make them intuitive
• Do not rely on documentation
• Provide switches for easy customization
• Prioritize flexibility and agility of code
• Design functions to handle one thing
33. Before
function buildPage()
{
var facebookIcon = "http://www.facebook.com/icon.png";
while (someConditionIsTrue()){
doSomeWork();
}
var i = resolveTwitterIcon();
}
!
var PinterestSmallLogo = pinterest();
!
buildPage();
34. Improving
function buildPage()
{
var iconFacebook = "http://www.facebook.com/icon.png";
while (someConditionIsTrue()){
doSomeWork();
}
var iconTwitter = resolveTwitterIcon();
}
!
var iconPinterest = pinterest();
!
buildPage();
35. After
function buildPage(icons)
{
icons.facebook = "http://www.facebook.com/icon.png";
while (someConditionIsTrue()){
doSomeWork();
}
icons.twitter = resolveTwitterIcon();
}
!
var
};
!
icons = {
facebook : "",
pinterest : pinterest(),
twitter : ""
buildPage(icons);
36. Habit Forming
• Adhere to strict coding style
• Remove comments
• Progressively generalize identifiers
• Identify similar patterns to normalize
• Code in anticipation for change
37. Generalize
• This will do something
• When something happens
• It will take some parameters
• Parameters will map to some object
• The outcome will be specific to context
38. Example
function initModules()
{
for (module in app.modules) {
if (app.modules[module].init && app.modules[module].checked()) {
if (app.modules[module].init.call(this, arguments)) {
initialized++;
}
}
}
}
function initModules()
{
var module;
for (moduleName in app.modules) {
module = app.modules[moduleName];
if (module.init && module.checked()) {
if (module.init.call(this, arguments)) {
initialized++;
}
}
}
}