JavaScript Beyond jQuery (Jfokus 2013)

101
@johnwilander JavaScript Beyond jQuery John Wilander

description

A presentation on the programming language JavaScript. It covers types, object orientation, variables and scope, closures, the Crockford Module Pattern, loading and executing, imports and namespacing, and more. The language features are compared to Java throughout the slides.

Transcript of JavaScript Beyond jQuery (Jfokus 2013)

Page 1: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript Beyond jQueryJohn Wilander

Page 2: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

shouldilearnjavascript.com

Page 3: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Part 1: Typing

Page 4: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Types

Primitive:string, number, boolean, function, undefined

The rest is object

Primitive:byte, short, int, long, float, double, boolean, char

The rest is objects, so called reference types

Java

JavaScript

Page 5: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Types

Primitive:string, number, boolean, function, undefined

Primitive:byte, short, int, long, float, double, boolean, char

Java

JavaScript

Page 6: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

TypesJava

JavaScript

Primitive:string, number, boolean, function, undefined

Primitive:byte, short, int, long, float, double, boolean, charStrings are not

general objects, they're a type

Page 7: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

TypesJava

JavaScript

Primitive:string, number, boolean, function, undefined

Primitive:byte, short, int, long, float, double, boolean, char

Only one type for numbers, i.e.

no difference between integers

or decimals

Page 8: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

TypesJava

JavaScript

Primitive:string, number, boolean, function, undefined

Primitive:byte, short, int, long, float, double, boolean, char Functions are full

objects with their own type

Page 9: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

TypesJava

JavaScript

Primitive:string, number, boolean, function, undefined

Primitive:byte, short, int, long, float, double, boolean, charJavaScript's

version of uninitialized is undefined

Page 10: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Static vs Dynamic Typing

Dynamic typing:var name; Variables have no typesname = ”John”; Values have typesname = 34; Variables change type dynamically

Static typing:String name; Variables have typesname = ”John”; Values have typesname = 34; Variables cannot change type

Java

JavaScript

Page 11: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Dynamic Typing

var name = ”John”;

JavaScript

Values have typesVariables haveno types

Page 12: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Strong vs Weak Typing

Page 13: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Strong !== goodWeak !== bad

Strong vs Weak Typing

Page 14: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

var dynVar = 4; Very weak typingdynVar + ""; Implicit type conversiondynVar + null; Implicit type conversiondynVar + []; Implicit type conversiondynVar + [0]; Implicit type conversion

int intVar = 4; Pretty strong typing"" + intVar; Implicit type conversionintVar + 0.0; Implicit, widening type conv.intVar + (int)0.0; Explicit type conversionintVar + null; Not allowed

Java

JavaScript

Strong vs Weak Typing

Page 15: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Type Safe≈

no type errors at runtime

Page 16: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

John's Conclusion

Java is a statically, strongly typed language with decent type safety

JavaScript is a dynamically, weakly typed language with decent type safety

Page 17: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Object Orientation

Page 18: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Java: Classes & Objects

Class

Object

Object

Object

Class Singleton

SourceExecuting

code

Page 19: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript: Functions, Object & Prototypes

Prototype

Function Function

SourceExecuting

code

Object

Object

Object

Page 20: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Prototype

Function

Function

SourceExecuting

code

Modules

Anonymous closures

Object

Object

Object

JavaScript: Functions, Object & Prototypes

Page 21: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Keywords in JavaScript

http://ariya.ofilabs.com/2012/03/most-popular-javascript-keywords.html

Statistics from:jQueryjQuery.MobilePrototypeExt JSMooToolsBackbone Underscore

Page 22: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Keywords in JavaScriptFunctions,functions,functions

Seldom new

Almost neverclasses as types

Page 23: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Java: Extension by Inheritance

Subclass

Super class

extends

Page 24: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Java: Subtyping by Inheritance

Super type

Subtype

extends

Page 25: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Through inheritanceJava classes get largerin terms of functions

andsmaller in terms of type

(more specific)

Page 26: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

In JavaScriptextension

andsubtyping

are separate things

Page 27: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Why do we want to subtype?

Because we think in terms of

static typing andis-a-relations

Page 28: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Static Typing and Subtyping

public void doPurchase(Item item)

Java

Accepts Itemor subtypes to Item

Page 29: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Dynamic Typing

public void doPurchase(Item item)

JavaScript

Page 30: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

public void doPurchase(Item item)

JavaScript

Dynamic Typing

Page 31: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

public void doPurchase(Item item)

JavaScript

Dynamic Typing

Page 32: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

public void doPurchase(Item item)

JavaScript

Dynamic Typing

Page 33: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

function doPurchase(item)__

JavaScript

Accepts anything... or nothing

Dynamic Typing

Page 34: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

function doPurchase(item)__

JavaScript

Can return anything... or nothing

Dynamic Typing

Page 35: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Part 2: To start a JavaScript program

Page 36: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript and Web<html><head> <script src=”js/main.js”></script> <script> var JW = {}; // More code </script></head><body> <button onclick="document.getElementById('field2').value=document.getElementById('field1').value">Copy text</button> <div> Some information </div> <script> JW.calcPrice = function(price, vat) { //… }; </script> <script src=”http://3rdparty.com/trackUsers.js”></script></body></html>

Page 37: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript and Web<html><head> <script src=”js/main.js”></script> <script> var JW = {}; // More code </script></head><body> <button onclick="document.getElementById('field2').value=document.getElementById('field1').value">Copy text</button> <div> Some information </div> <script> JW.calcPrice = function(price, vat) { //… }; </script> <script src=”http://3rdparty.com/trackUsers.js”></script></body></html>

Script from file in <head>Synchronous loading and

execution

Page 38: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript and Web<html><head> <script src=”js/main.js”></script> <script> var JW = {}; // More code </script></head><body> <button onclick="document.getElementById('field2').value=document.getElementById('field1').value">Copy text</button> <div> Some information </div> <script> JW.calcPrice = function(price, vat) { //… }; </script> <script src=”http://3rdparty.com/trackUsers.js”></script></body></html>

Inlined script in <head>Synchronous execution before DOM is loaded

Page 39: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript and Web<html><head> <script src=”js/main.js”></script> <script> var JW = {}; // More code </script></head><body> <button onclick="document.getElementById('field2').value=document.getElementById('field1').value">Copy text</button> <div> Some information </div> <script> JW.calcPrice = function(price, vat) { //… }; </script> <script src=”http://3rdparty.com/trackUsers.js”></script></body></html>

Script directly in HTML, executed on click event

Page 40: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript and Web<html><head> <script src=”js/main.js”></script> <script> var JW = {}; // More code </script></head><body> <button onclick="document.getElementById('field2').value=document.getElementById('field1').value">Copy text</button> <div> Some information </div> <script> JW.calcPrice = function(price, vat) { //… }; </script> <script src=”http://3rdparty.com/trackUsers.js”></script></body></html>

Inlined script in <body>Executed when the

parser gets here

Page 41: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JavaScript and Web<html><head> <script src=”js/main.js”></script> <script> var JW = {}; // More code </script></head><body> <button onclick="document.getElementById('field2').value=document.getElementById('field1').value">Copy text</button> <div> Some information </div> <script> JW.calcPrice = function(price, vat) { //… }; </script> <script src=”http://3rdparty.com/trackUsers.js”></script></body></html>

Script from file in <body>Loaded and executed synchronously

Page 42: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Good Practice:

1. All JavaScript on file.

2. All statically loaded JavaScript in one block.

Page 43: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Dynamic Loading(function(){ var oldFirstScript = document.getElementsByTagName('script')[0]; newScript = document.createElement('script'),

newScript.async = true; newScript.src = 'js/script.js';

oldFirstScript.parentNode.insertBefore( newScript, oldFirstScript);}());

Page 44: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

OK, that's loading.But I want to start.

Page 45: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

In the Beginning

(function(){}());

window.someGlobalFunction();

public static void main(String[] args)

Java

JavaScript

Page 46: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Self-Invoking Functions

Anonymous, self-invoking with parameter(function(me) { // Code}('John'));

Anonymous, self-invoking without parameter(function() { // Code}());

Page 47: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Part 4: Variables

Page 48: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Scopevar GLOB = {};

GLOB.func = function(array) { var local = …; … for (var i=0; i<array.length; i++){ … var temp = array[i]; }};

JavaScript

Page 49: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Scopevar GLOB = {};

GLOB.func = function(array) { var local = …, i, temp; … for (i=0; i<array.length; i++){ … temp = array[i]; }};

JavaScript

Page 50: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Scopevar GLOB = {};

GLOB.func = function(array) { var local = …, i, temp; … for (i=0; i<array.length; i++){ … temp = array[i]; }};

JavaScript

There are only two variable scopes:Global or local function scope.

All local variables are hoisted tothe top of the function.

Page 51: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Closure(function(array) { var i, temp; … for (i=0; i<array.length; i++){ … temp = array[i]; }}([1, 2, 3]));

JavaScript

Page 52: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Closure(function(array) { var i, temp; … for (i=0; i<array.length; i++){ … temp = array[i]; }}([1, 2, 3]));

JavaScript

A closure keeps its scope and itscontext during its life span.

A reference ending up inside theclosure (array above) will keep its value inside the closure.

Page 53: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Closure Pitfallfor(i=0; i<pages.length; i++) { var page = pages[i]; pageElement.load(page.url, function() { launchForm(page.form); });}

JavaScript

Page 54: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

for(i=0; i<pages.length; i++) { var page = pages[i]; pageElement.load(page.url, function() { launchForm(page.form); });}

JavaScript

Callback function sincepageElement.load()is asynchronous

Closure Pitfall

Page 55: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

for(i=0; i<pages.length; i++) { var page = pages[i]; pageElement.load(page.url, function() { launchForm(page.form); });}

JavaScript

page is hoisted and thus gets a new value for each iteration

Closure Pitfall

Page 56: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

var page;for(i=0; i<pages.length; i++) { page = pages[i]; pageElement.load(page.url, function() { launchForm(page.form); });}

JavaScriptClosure Pitfall

page is hoisted and thus gets a new value for each iteration

Page 57: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

var page;for(i=0; i<pages.length; i++) { page = pages[i]; pageElement.load(page.url, function() { launchForm(page.form); });}

JavaScript

When the callback is run page will refer to pages[pages.length-1] or at least another value than intended.

Closure Pitfall

Page 58: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

var page;for(i=0; i<pages.length; i++) { page = pages[i]; pageElement.load(page.url, function() { launchForm(page.form); });}

JavaScriptClosure Pitfall

Page 59: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

var page;for(i=0; i<pages.length; i++) { page = pages[i]; (function(page) { pageElement.load(page.url, function() { launchForm(page.form); } }); })(page);}

JavaScriptMaking Use of Closures

Page 60: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

var page;for(i=0; i<pages.length; i++) { page = pages[i]; (function(page) { pageElement.load(page.url, function() { launchForm(page.form); } }); })(page);}

JavaScript

We bind page to a new closureso that the callback refers correctly

Making Use of Closures

Page 61: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Part 5: The Crockford Module

orModule Pattern

With self-invoking functions,scope, and closures we are ready forthe most important design pattern:

Page 62: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){}());

JavaScript

Page 63: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ return {};}());

JavaScript

Page 64: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ return { getPatient: function(personnummer) {

} };}());

JavaScript

Page 65: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ var cache = {}; return { getPatient: function(personnummer) {

} };}());

JavaScript

Page 66: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ var cache = {}; return { getPatient: function(personnummer) { var res=cache[personnummer]; // Check if fresh // Return } };}());

JavaScript

Page 67: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ var cache = {}; return { getPatient: function(personnummer) { var res=cache[personnummer]; if(_isValid(res)) { return res.patient; } else { // Handle cache miss } } };}());

JavaScript

Page 68: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ var cache = {}, _isValid = function(res) {

} return { getPatient: function(personnummer) { var res=cache[personnummer]; if(_isValid(res)) { return res.patient; } else { // Handle cache miss } }

JavaScript

Page 69: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ var cache = {}, _isValid(res) { return !res ? false : (Date.now() - res.timestamp) <= 60000; // One minute } return { getPatient: function(personnummer) { var res=cache[personnummer]; if(_isValid(res)) { return res.patient; } else { // Handle cache miss

JavaScript

Page 70: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

JW.cache = (function(){ var cache = {}, _isValid(res) { return !res ? false : (Date.now() - res.timestamp) <= 60000; // One minute } return { getPatient: function(personnummer) { var res=cache[personnummer]; if(_isValid(res)) { return res.patient; } else { // Handle cache miss

JavaScript

We can have (closure) privatevariables and functions

Page 71: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Crockford = (function(initParam) { var privVar1, privVar2, _privFunc1 = function() {

}, _privFunc2 = function() {

}; return { pubVar1: ”value”, pubFunc1: function() {

} };}(initParam));

JavaScript

Page 72: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Part 6:Named Parameters

Page 73: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Method Signatures

function execPurchase(price, item, discountCode, wantsSpam, user)

public void execPurchase(int, String, String, boolean, User)

Java

JavaScript

Page 74: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

function execPurchase(purchase) { purchase.price … purchase.item … purchase.wantsSpam … purchase.user …

builder = new Purchase.Builder();Purchase purchase = builder.setPrice(9900) .setItem(”cap”).wantsSpam(false) .setUser(user).build();

Java

JavaScript

Method Signatures

Page 75: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Part 7: Asynchronous Module Definition

(AMD) with require.js

Page 76: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Concatenateand minify

Page 77: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

You may want to separatethird party code to be ableto cache it harder.

Concatenateand minify

Page 78: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

The goal is to mimimize the number of HTTP requests and the size of data over the wire.

Concatenateand minify

Page 79: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

Tools for Concatenation and Minification

• Google Closure Compiler

• UglifyJS

• require.jsConcatenates and minifies with Closure Compiler or UglifyJS

Page 80: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

require.js – import and namespace in JavaScript

Page 81: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

require([ "backbone", "underscore", "models/CartModel", "text!templates/CartItem.html"], function (Backbone, _, CartModel, cartItemTemplate) {

// Code dependent on Backbone etc

});

Page 82: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

require([ "backbone", "underscore", "models/CartModel", "text!templates/CartItem.html"], function (Backbone, _, CartModel, cartItemTemplate) {

// Code dependent on Backbone etc

});

paths : { jquery : "vendor/jquery.min", backbone : "../components/backbone/backbone-min", underscore : "../components/underscore/underscore"}

main.js

Page 83: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

require([ "backbone", "underscore", "models/CartModel", "text!templates/CartItem.html"], function (Backbone, _, CartModel, cartItemTemplate) {

// Code dependent on Backbone etc

});

File system, like Java packages

Page 84: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

require([ "backbone", "underscore", "models/CartModel", "text!templates/CartItem.html"], function (Backbone, _, CartModel, cartItemTemplate) {

var model = new CartModel();

});

Local name, likedependency injection

Page 85: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

define([ "backbone", "underscore", "models/CartModel", "text!templates/CartItem.html"], function (Backbone, _, CartModel, cartItemTemplate) {

var CartItemView = …;

return CartItemView;});

Define new modules

Page 86: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

CartItemView.js

Page 87: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

index.html without require.js or the like

<head> <script src="js/lib/jquery-1.9.0.min.js"></script> <script src="js/lib/jquery-encoder-0.1.0.js"></script> <script src="js/base.js"></script> <script src="js/JW/util/util.js"></script> <script src="js/JW/personnummer/Personnummer.js"></script> <script src="js/JW/patient/Patient.js"></script>…

<script src="js/JW/cache/cache.js"></script> <script src="js/JW/proxy/proxy.js"></script> <script src="js/JW/gui/gui.js"></script></head>

… manually, in the right order.

Page 88: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

index.html with require.js

<head> <script data-main="scripts/main" src="scripts/require.js" > </script></head>

Page 89: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

index.html with require.js

<head> <script data-main="scripts/main" src="scripts/require.js" > </script></head>

require.config({ … paths : { jquery : "vendor/jquery.min", backbone : "../components/backbone/backbone-min", underscore : "../components/underscore/underscore" }});

require(["app"], function (App) { App.start();});

main.js

Page 91: JavaScript Beyond jQuery (Jfokus 2013)

@johnwilander

The Streamhttp://javascriptweekly.com/

@javascript_news@BrendanEich @littlecalculist@addy_osmani @addyosmani

@paul_irish @badass_js@rwaldron @slicknet

@kangax @unscriptable@sthlmjs

Page 92: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

dojo-release-1.8.3.zip 11 Mb

ext-4.1.1a-gpl.zip 45,7 Mb ext-all.js 1 Mb

yui_3.8.1.zip 28,1 Mb

Page 93: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVC

SimplifiedDom api& shims

Page 94: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVC

jQuery

Modernizr

underscore

SimplifiedDom api& shims

Page 95: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVC

Handlebars

MustachSimplifiedDom api& shims

Page 96: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVC

BackboneEmber

angular

SimplifiedDom api& shims

Page 97: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVCSpine

SimplifiedDom api& shims

Page 98: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVC

jQuery UI

Bootstrap

SimplifiedDom api& shims

Page 99: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Widgets

Templates

MVC

Ext JSDojoYUI

SimplifiedDom api& shims

Page 100: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

All-in-one frameworks are best suited for newly written single-purpose applications without mashup behavior.

Page 101: JavaScript Beyond jQuery (Jfokus 2013)

@joakimkemeny & @johnwilander

Micro frameworks are better if you need to integrate legacy code, some nifty CMS product, or if you have logic/content from third parties.

Micro frameworks don't ”take over” you application.