Week 2:
electric boogalo

i.e. Javascript

Recap

Policy: don't miss class!
Homework: only one game
Groups: up to 4

recap

HTML is a tree-based markup language for web pages.
<!DOCTYPE html>
<html>
    <head>
        <title>Hello, World</title>
        <link href="style.css" re="stylesheet">
    </head>
    <body>
        <div id="container">
            <h1>Under Construction</h1>
            <div class="column">
                We're under construction!
            </div>
            <div class="column">
                <input type="text" placeholder="Name">
                <input type="text" placeholder="Email">
            </div>
        </div>
    </body>
</html> 

Recap

CSS is a structured series of rules for styling documents.
body { 
   background: grey; 
   font-family: 'Comic Sans', 'Helvetica', sans-serif;
}

#container {
    position: absolute;
    left: 50%; right: 50%;
    width: 500px; height: 300px;
    margin-left: -250px; 
    margin-top: -150px;
    overflow: auto;
}

.column {
    float: left;
    width: 250px;
} 

WHAT is javascript?

JavaScript is:
  • Interpreted
  • Dynamically typed
  • Object-oriented (sort of)
  • Garbage-collected
  • Functional (sort of)
  • Semi-standard (at best)
  • Your worst nightmare

TYPES

  • Numbers - 3.14
  • Booleans - true
  • Strings - "hello world"
  • Undefined - undefined
  • Objects - {foo: "bar"}
  • Functions - function(){}


That's it! Most things are objects.


TYPES - OHGODWHY

var a = "9";
console.log(a + "1");  // prints "91"
console.log(a + 1);    // prints ??
console.log(a - 1);    // prints ?? 

var b = "10";
console.log(1 + +b);  // prints 11
console.log(1++b);    // prints ??

console.log([] + []);                 // prints "" 
console.log(+["1"]/2 + (+[]) - []*2); // I quit

VARIABLES

Usual naming conventions. [\w_$][\w\d_$]*

Declare variables with the var  or  function  keywords.

var a = 1;
a = "foo";

var b = function() {}

function c(arg) {
    console.log(arg);
} 

LITERALS

You can declare literals in a number of ways:
var a = 3.14,
    b = "hello",
    c = false,
    d = [1, 2, 3],
    e = {foo: "bar"}; 

Objects are just key/value pairs.
console.log(e.foo, e["foo"]);
e.foo = "hello, world";
e[1] = true;

SCOPING

Declaring w/ var  always puts in scope.
Scope is defined by functions only!
if (true) {
    var a = true;
}
console.log(a); // prints true 

Variables are also hoisted.
console.log(foo);      // prints undefined (but not error)
var foo = "bar";

(function(){
    console.log(foo);  // prints undefined (not "bar")
})(); 

150 strikes back

Functions are values!
function run5(f){ f(5); }

run5(function(n){
   console.log(n + 1);  
}); // prints 6 
Functions are also closures.
function adder(increment){
    var num = 0;
    return function(){
        num += increment;
        return num;
    }
}

var add2 = adder(2);
console.log(add2());  // prints 2
console.log(add2());  // prints 4 

PARAMETERS

The arguments  variable comes in handy.
function logger() {
    console.log(arguments.length);
    console.log.apply(console, arguments);
}

logger(1, "2", [3]); // prints 3 and then the three values 
You can also have optional parameters.
function increment(i, debug){
    if (debug) {
        console.log("increment called on " + i);
    }
    return i + 1;
}

console.log(increment(0)); // just prints 1
console.log(increment(1, true)) // prints "increment called on 1" then 2

BUILDING BLOCKs

JavaScript blocks look like most other languages.
var a = [1, 2, 3];

if (a[0] == 1){
    // something
} else {
    // something else
}

for (var i = 0; i < a.length; i++) {
    console.log(a[i]);
}

while(true) {
    a[0]++;
} 

Also: switch, try/catch, and for...in

That's the basics!

As for the basics, anyway. Other semi-important topics:
  • Regular expressions - str.match(/pattern/)
  • Default libraries - strings, arrays, math
  • Other operators - ===, && , ||, ?:
  • Object parameters by reference

OOP-s!

Can't forget about JavaScript classes...

oOP basics

Weird facts about JS classes:
  1. There are no classes, really.
  2. Each class is a function.
  3. Each function is actually an object.
  4. But these objects aren't instances.
  5. Instantiation is just like function calling,
    but with new  in the front.
  6. Instantiation returns an object.

OOP BASICS

Let's make all that clearer.

Classes: constructors + methods.
Instances: objects, just regular 'ol maps.
function Animal() {}
var Will = new Animal();
var James = new Animal(); 

function Animal(name) {
    this.name = name;
}
var Will = new Animal('Will');
console.log(Will.name);         // prints "Will" 

PROTOTYPES

Methods show up in prototypes.
function Animal(name) {
    this.name = name;
}

Animal.prototype.talk = function() {
    console.log('My name is ' + this.name);
}

var Will = new Animal('Will');
Will.talk(); // prints "My name is Will" 
    
var func = Will.talk;
func(); // prints "My name is"

func.call({name: 'Slim Shady'}); // prints "My name is Slim Shady"

WAIT, PROTOTYPES?

In Java/C++, classes are like templates for instances.
JavaScript is class-less (instance-based),  
i.e. lazy and uses objects as classes.

"The the class-less programming style has grown increasingly popular, and has been adopted for programming languages such as JavaScript, Cecil, NewtonScript, Io, MOO, REBOL, Kevo, Squeak and several others."

Hence, we get prototypes--objects that are
copied to all instances (with new).

INHERITANCE

Prototypes make inheritance... interesting.
function Animal(name){ ... }
Animal.prototype = { ... }
function Dog(name) {
    Animal.call(this, name);    
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.woof = function() {
    console.log('MOO');
    this.talk();
}

var Will = new Dog('Will');
Will.woof(); // prints "MOO" and "My name is Will"

this/that

"this" refers to the calling context, 
often used to reference the object on which
the function is called.
Animal.prototype.talk = function() {
    console.log("My name is " + this.name);
}

this is ONLY assigned through dot notation calls.
var will = new Animal('Will');
will.talk(); // My name is Will

var func = will.talk
func(); // My name is 

binding problem

function talkThrice(f) {
    f(); f(); f();
}

talkThrice(will.talk); // prints empty lines! 

Solution: closures!
function talkThrice(f) {
    f(); f(); f();
}

talkThrice(function(){ will.talk(); });  

js applications

Doing it right

jQuery

Library for DOM manipulation (and more!)
Most popular JS framework.

Great for:
  • Doing operations on DOM elements
    • CSS
    • Animation
  • Handling events (click, hover, key)
  • Ajax (Asynchronous JavaScript and XML)
  • Plugins!

jquery - dom/events

$('#container').css('width', '100px'); 

$('.box').animate({ top: '+=50' }, function() {
    console.log('Animation finished');
}) 

$('a').click(function(){ 
    alert('WARNING: LINK CLICKED');
}) 

jquery - ajax

$.ajax({
  url: 'https://api.forecast.io/forecast/1b7f8a378848cf9eeaff18f73eaed6c5/40.4383,-79.997
  dataType: 'jsonp',
  success: function(data) {
    var conditions = data.currently;
    var message = "In Pittsburgh, it's currently " + 
                   conditions.summary + " and " + 
                   conditions.temperature + " degrees."
    alert(message);
  }
});

underscore

Library for making your code better.

Utilities include:
  • arrays (mapreduce, findWhere, ...)
  • functions (bind, defer, wrap)
  • objects (keys, extend) 

Remember our this problem?
function talkThrice(f) {
    f(); f(); f();
}

talkThrice(_.bind(will.talk, this));  

app organization

Moving from the realm of code -> design.
How do you structure an efficient, maintainable app?

Mostly, it boils down to encapsulation,
i.e. limiting scope and using classes to 
keep related methods together.

modular pattern

Common idiom in JavaScript is the 
modular pattern.
(function() {
    'use strict';
    var myLocalVariable = ...
})();console.log(myLocalVariable) // prints 'undefined'

Or for populating a namespace,
var Module = (function() {
    'use strict';
    return { foo: 'bar' }
})(); console.log(Module.foo) // prints 'bar'

requirejs

Use RequireJS for easy modules and
simple dependency management.
define(function(require) {
    'use strict';

    var $ = require('jQuery');
    $('#yes').html('no');
}) 

sample app structure

Organize the files in a logical way.
myproject/
-> index.html
-> style.css
-> images/
    -> *.(png|jpg|...)
-> js/
    -> vendor/
        -> 3rd party libraries
    -> app.js
    -> constants.js
    -> MyClass.js
    -> other files... 

sample app structure

No inline CSS or JavaScript!
<!DOCTYPE html>
<html>
    <head>
        <title>My Project</title>
        <link href="style.css" rel="stylesheet">
    </head>
    <body>
        <div id="container">
            <!-- body html here -->
        </div>
        <script data-main="js/app" src="js/vendor/require.js"></script>
    </body>
</html> 

sample app structure

Set up RequireJS and initialize app in app.js.
define(function(require) {
    'use strict';

    requirejs.config({
        urlArgs: 'bust=' + (new Date()).getTime(),
        shim: {
            'jQuery': { exports: '$' }
        },
        paths: {
            'jQuery': 'vendor/jquery-2.0.3.min',
        }
    });

    require(['Game'], function(Game) {
        var gameInstance = new Game();
        gameInstance.run();
    })
});

That's it!

You're ready to venture out into the wild
and make solid JS applications.


Made with Slides.com