The NEEDNT Foods List: Non-Essential Energy Dense Nutritionally Deficient Foods
JavaScript Neednt Hurt - JavaBin talk
-
Upload
thomas-kjeldahl-nilsson -
Category
Documents
-
view
864 -
download
0
Transcript of JavaScript Neednt Hurt - JavaBin talk
![Page 1: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/1.jpg)
JavaScript Needn’t Hurt!
Thomas Kjeldahl [email protected]
linkedin.com/in/thomaskjeldahlnilssontwitter.com/thomanil
![Page 2: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/2.jpg)
![Page 3: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/3.jpg)
![Page 4: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/4.jpg)
What Are We Covering Today?
Language basicsHtml scripting
Good practicesTools
10,000 ft view!
![Page 5: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/5.jpg)
History Lesson
![Page 6: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/6.jpg)
![Page 7: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/7.jpg)
Brendan Eich
![Page 8: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/8.jpg)
2 WEEKS
![Page 9: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/9.jpg)
(cond ((good? x) (handle-good x)) ((bad? x) (handle-bad (if (really-bad? x) (really-bad->bad x) x))) ((ugly? x) (handle-ugly x)) (else (handle-default x)))
![Page 10: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/10.jpg)
(cond ((good? x) (handle-good x)) ((bad? x) (handle-bad (if (really-bad? x) (really-bad->bad x) x))) ((ugly? x) (handle-ugly x)) (else (handle-default x)))
![Page 11: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/11.jpg)
What Sucks?Rushed out the door
Some bad language featuresCrossbrowser problems
![Page 12: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/12.jpg)
What Rocks?Powerful, elegant, dynamic
Present & enabled for most usersNot confined to the browser
Small learning surface
![Page 13: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/13.jpg)
Language Basics
SyntaxTypes
VariablesObjects
Functions
![Page 14: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/14.jpg)
Basic SyntaxSimilar to Java, C#
Operators, statementsif-else, while, for, try-catch-finally
Still in Kansas...
![Page 15: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/15.jpg)
TypesStrings
NumbersBooleans
ObjectsArrays
![Page 16: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/16.jpg)
Variable Declarations
var x = “foo”; // stringvar x = 2; // numbervar x = true; // booleanvar x = { }; // objectvar x = [ ]; // array
![Page 17: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/17.jpg)
Objects
![Page 18: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/18.jpg)
Object CreationLiteral Form
var basicProject = { name : "Steria Workshop", version : 1.2,
getName : function() { return this.name; } };
![Page 19: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/19.jpg)
Object CreationDynamic Form
var basicProject = {};
basicProject.name = "Steria Workshop";basicProject.version = 1.2;
basicProject.getName = function() { return this.name;};
![Page 20: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/20.jpg)
Objects as Maps(Associative Arrays)
var person = { firstname:"John", lastname:"Smith" };
person.firstname; // => "John" (Access using identifier)person["firstname"]; // => "John" (Access using variable name)
![Page 21: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/21.jpg)
Arrays and ObjectsCan Be Deeply Nested
var outerObject = { innerArray : [ innerObject : { deepestArray : [1,2,3] } ]};
![Page 22: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/22.jpg)
JSON
{"firstName":"Gustav","lastName":"Adolf","roles":["King of Sweden","Terrible shipbuilder"],"other":{"birth":"9.12.1594","death":"16.11.1632"}}
![Page 23: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/23.jpg)
Kind Familiar Looking
{ "firstName" : "Gustav", "lastName" : "Adolf", "roles" : [ "King of Sweden", "Terrible shipbuilder" ], "other" : { "birth" : "9.12.1594", "death" : "16.11.1632" }}
![Page 24: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/24.jpg)
JavaScriptObject Literal!
var evaluatedObject = { firstName : "Gustav", lastName : "Adolf", roles : [ "King of Sweden", "Terrible shipbuilder" ], other : { birth : "9.12.1594", death : "16.11.1632" }};
![Page 25: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/25.jpg)
Inheritance
![Page 26: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/26.jpg)
What is OOP?
![Page 27: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/27.jpg)
Prototypal Inheritance (Simplified)
var employee = {name : "CEO Jack", company : "ACME Inc."};var janitor = Object.create(employee);
// Janitor now looks and behaves just like its prototype, Employeejanitor.company // => "ACME Inc.", chains back to prototype.company
janitor.name = "Janitor Tim"; // Shadow namejanitor.tools = ["broom", "bucket"]; // Define member variable only on child
employee.name = "CEO Jane"; // Change name of prototypejanitor.name; // => Still "Janitor Tim". Shadowed members unaffected by prototype
changes
![Page 28: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/28.jpg)
Flexibility!
![Page 29: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/29.jpg)
Functions
![Page 30: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/30.jpg)
Simple Function Definition
function add(a, b) { return a + b;}
![Page 31: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/31.jpg)
Roughly Same Result:
var add = function(a, b) { return a + b;};
// Use this consistently// Helps you remember:// Functions are just variables!
![Page 32: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/32.jpg)
An AnonymousFunction...
function(element) { // Do something with element}
![Page 33: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/33.jpg)
...Can Be SentTo Another Function
each(collection, function(element) { // Do something with current element});
![Page 34: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/34.jpg)
Example:Event Handler
button.onClick(function(element) { alert(«You clicked me!»);});
![Page 35: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/35.jpg)
![Page 36: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/36.jpg)
![Page 37: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/37.jpg)
Sharp EdgesGlobal variablesNo block scope
Semicolon insertion== operator
![Page 38: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/38.jpg)
Properly ScopedVariable
var getSmallNumber = function(){ var smallNumber = 42; // Note use of var keyword return smallNumber;};
![Page 39: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/39.jpg)
Sloppy,Global Variable
var getSmallNumber = function(){ smallNumber = 42; return smallNumber;};
// Missing var prefix = smallNumber gets global scope// Becomes available for all code// Sticks around and pollutes namespace
![Page 40: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/40.jpg)
No Block Scope
var x = 1;
if (true) { var x = 123;
} // x => 123
![Page 41: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/41.jpg)
Semicolon insertion
Don't force the browser to guess!
![Page 42: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/42.jpg)
Example
a = b + c(d + e).print()
becomes...
a = b + c(d + e).print();
![Page 43: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/43.jpg)
== vs ===
![Page 44: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/44.jpg)
Quiz
'' == '0' // true or false?0 == '' // true or false?0 == '0' // true or false?false == 'false' // true or false?false == '0' // true or false?false == undefined // true or false?false == null // true or false?null == undefined // true or false?' \t\r\n ' == 0 // true or false?
![Page 45: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/45.jpg)
How ManyDid You Get?
'' == '0' // false0 == '' // true0 == '0' // truefalse == 'false' // falsefalse == '0' // truefalse == undefined // falsefalse == null // falsenull == undefined // true' \t\r\n ' == 0 // true
// Why? Type coercion on right operand!
![Page 46: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/46.jpg)
Instead, Use ===(And !==)
'' === '0' // false0 === '' // false0 === '0' // falsefalse === 'false' // falsefalse === '0' // falsefalse === undefined // falsefalse === null // falsenull === undefined // false' \t\r\n ' === 0 // false
![Page 47: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/47.jpg)
ClientsideDOM scripting
jQueryFirebug
![Page 48: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/48.jpg)
The DOM
![Page 49: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/49.jpg)
![Page 50: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/50.jpg)
<TABLE> <TBODY> <TR> <TD>Shady Grove</TD> <TD>Aeolian</TD> </TR> <TR> <TD>Over the River, Charlie</TD> <TD>Dorian</TD> </TR> </TBODY> </TABLE>
![Page 51: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/51.jpg)
![Page 52: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/52.jpg)
DOM ScriptingBasics
x.getElementById(id) ; // get the element with a specified id
x.getElementsByTagName(name); // get all elements with a // specified tag name
x.appendChild(node); // insert a child node to xx.removeChild(node), // remove a child node from x
x.innerHTML = «<p>New text</p>»; // fill element with html or text
![Page 53: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/53.jpg)
DOM Api:Crossbrowser Headache
http://www.quirksmode.org
![Page 54: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/54.jpg)
Use Frameworks
![Page 55: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/55.jpg)
jQuery
![Page 56: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/56.jpg)
Instant Win:CrossbrowserNon-verbose
Traverse DOMManipulate DOM
![Page 57: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/57.jpg)
Lots of Other Stuff, TooServer communicationUI widgets and effects
each(), map(), etcJSON parsing
+++
![Page 58: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/58.jpg)
jQuery Function
$() // Short formjQuery() // Long form
![Page 59: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/59.jpg)
Find Stuff
$(“p”); // Find all paragraphs$(“#shoppingList”); // Find element with id 'shoppingList'$(“.shoppingListItem”); // Find elements with class 'shoppingListItem'$(“:text”); // Find all text elements$(“:visible”); // Find only visible elements
![Page 60: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/60.jpg)
$() Wraps and Returns Matching Element(s)
![Page 61: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/61.jpg)
Manipulate MatchedDOM Elements
$(“p”).css(”color”, ”green”); // Set color on all paragraph elements$(“p”).hide(); // Hide all paragraphs
// Make all input buttons react to mouse clicks$(“input”).click(function(){ alert(”You clicked this button!”); });
![Page 62: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/62.jpg)
ChainingEvery API call returns jQuery object
So we can chain function calls together“Fluent API”
![Page 63: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/63.jpg)
Chaining Example
// Set color on all paragraph elements, then hide them all$(“p”).css(”color”, ”green”).hide();
![Page 64: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/64.jpg)
Caution!Use frameworks as neededBut don't depend on them!
JavaScript != jQuery
![Page 65: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/65.jpg)
Example
![Page 66: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/66.jpg)
Good PracticesFirebug
jsLintUnobtrusive JavaScript
Automated testing
![Page 67: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/67.jpg)
![Page 68: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/68.jpg)
JsLint
![Page 69: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/69.jpg)
![Page 70: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/70.jpg)
Unobtrusive JavaScript
Structure vs behaviorSeparate js files
Event handler setupNamespaces
Universal Access
![Page 71: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/71.jpg)
![Page 72: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/72.jpg)
![Page 73: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/73.jpg)
![Page 74: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/74.jpg)
![Page 75: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/75.jpg)
![Page 76: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/76.jpg)
Namespace Hygiene
All your code within single object
![Page 77: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/77.jpg)
Universal Access
Can all your users use your site?Users without JS?
Blind users with screen readers?Use progressive enhancement
![Page 78: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/78.jpg)
Crossbrowser Dev Process
Frameworks > raw DOM Clean, disciplined code
Test early, test often
![Page 79: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/79.jpg)
Automated Testing
See the next talk... :)
![Page 80: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/80.jpg)
References & Further Study
![Page 81: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/81.jpg)
![Page 82: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/82.jpg)
![Page 83: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/83.jpg)
Web Resourceshttp://javascript.crockford.comhttp://cjohansen.no/javascript
http://ajaxian.com
![Page 84: JavaScript Neednt Hurt - JavaBin talk](https://reader031.fdocuments.in/reader031/viewer/2022022419/54be38774a795921378b46dc/html5/thumbnails/84.jpg)
Best Way to Learn:
Start Building!
http://ajaxian.com/archives/writing-a-javascript-tetris-lessons-learned-from-a-ruby-chap