javascript primer
DESCRIPTION
A primer for JavaScript that covers from basic variable definition to scoping, "this", and a brief foray into the DOM and jQuery.TRANSCRIPT
JavaScriptA Primer In Far Too Many Parts
History
MochaLiveScript
JavaScript
Brendan EichCTO, Mozilla Corp.
April 1995
JavaScript
ECMAScript
ActionScript
JScript
Basics
Data Types
• number
• string
• boolean
• object
• null
• NaN
• undefined
Strings
• Are Objects, have methods
"Foo" + "Bar"; //"FooBar"
var str = "Lorem Ipsum Dolor Sit Amet";
str.toLowerCase(); //"lorem ipsum dolor sit amet"str.toUpperCase(); //"LOREM IPSUM DOLOR SIT AMET"str.split(" "); //["Lorem", "Ispum", "Dolor", "Sit", "Amet"]str.substring(6,9); //"Ips"
new String("Lorem Ipsum Dolor Sit Amet") == str; //true
Strings
parseInt("56"); //56parseInt("42.567"); //42parseInt("asdf"); //NaNparseInt("5a6"); //5parseFloat("24.68"); //24.68parseFloat("asdf"); //NaNparseFloat("24a"); //24
String to Number
Objects
• “Dictionary” / “Associative Array”
• Key: Value or 'Key': Value
• Without ': A-Z0-9 only
• Does not keep intrinsic ordering
• Accessed keys using . (dot) or [] notation
var object = { foo: 'value', 'complex key': 0, bar: { nested: true }};
object.foo; //'value'object.['complex key']; //0object.bar.nested; //trueobject.bar['nested']; //trueobject['bar'].nested; //trueobject['bar']['nested']; //true
Objects
in or hasOwnProperty()
• Tough call:
• .hasOwnProperty() more consistent
• in checks inherited properties
• Used in for loop
var test = { foo: 'value', bar: 'value', baz: 'value'}
for (var key in test) { console.log(key + ": " + test[key]);}
//PRINTS://foo: value//bar: value//baz: value
in
Arrays
• Special object
• Numerical keys only
• Keeps intrinsic ordering
• Short ([]) and Long (new Array()) syntax
var arrayShort = [ 'one', 'two'];arrayShort[2] = 'three';
var arrayLong = new Array();arrayLong[0] = 'one';arrayLong[1] = 'two';arrayLong[2] = 'three';
//arrayShort: ["one", "two", "three"]//arrayLong: ["one", "two", "three"]
Arrays
var arr = [1,2,3,4,6];
arr.indexOf(2); //1arr.join(':'); //"1:2:3:4:6"arr.pop(); //6 //[1,2,3,4]arr.push(7); //5 //[1,2,3,4,7]arr.reverse(); //[7,4,3,2,1]arr.shift(); //1//[2,3,4,7]arr.unshift(8); //5//[8,2,3,4,7]arr.slice(1); //[2,3,4,7]arr.slice(1,3); //[2,3]arr.slice(-3); //[3,4,7]arr.slice(-3,-1); //[3,4]
Arrays
var arr1 = [1,2,3];var arr2 = [3,4,5];
arr1.concat(arr2); //[1,2,3,3,4,5]
Arrays
Functions
• Are Objects as well
• “Elevated”
• You can use a named function before it is defined in code
• Function definitions are elevated to the top
function Foo() { //...}
Foo(); //validBar(); //valid
function Bar() { //...}
Functions
function Foo() { }
Foo.bar = "value";
'bar' in Foo; //trueFoo.bar == "value"; //true
Functions
Function Arguments
• No way to assign default arguments
• But arguments are not required
• If an argument is not specified, it is set to undefined
arguments
• A special variable found inside a function
• A not-quite array object containing all the function arguments
function sum() { var x = 0; for (var i = 0; i < arguments.length; ++i) { x += arguments[i]; } return x;}sum(1, 2, 3); //6
arguments
typeof
• Determines a variables type
• Returns a string
typeof true; //"boolean"typeof 12; //"number"typeof "string"; //"string"typeof []; //"object"typeof {}; //"object"typeof NaN; //"number"typeof null; //"object"typeof undefined; //"undefined"
function Foo() {}typeof Foo; //"function"
typeof
Comparison
• a == b / a != b
• A and B compared by value alone
• 1 == “1” evaluates to true
• a === b / a !== b
• A and B compared by value and by type
• 1 === “1” evaluates to false
window, document• Built in, global, Objects
• window
• Provides access to the browser window
• The “global” object: foo === window.foo
• Things like window.location.href, etc
• document
• Provides access to the current DOM
Scoping
Global & Local
• Functions are the only way to create new scopes
• Variables defined with var are local
• Variables defined without var are global
• Global variables are members of window
var outerScope = 10;var outerScope2 = 10;
function Foo() { var outerScope = 20; var innerScope = 20; globalVariable = 30; outerScope2 = 40;}
Foo();
alert(outerScope); //10alert(outerScope2); //40alert(innerScope); //erroralert(globalVariable); //30
Global & Local
function Foo() { var baz = 1; return Bar();}
function Bar() { return baz;}
Foo(); //baz is not defined
Lexical Scopingfunction Foo() { var baz = 1; function Bar() { return baz; } return Bar();}
Foo(); //1
Closures
Closures
• First-Class
• Can assign functions to variables, pass as arguments and return as values
• Anonymous
• Not required to have a name
• A function that “closes over” variables defined outside itself
function Foo() { var count = 0; return function() { count = count + 1; return count; };}
var bar = Foo();
bar(); //1bar(); //2bar(); //3
Closures
function createAdder(amount) { return function(input) { return input + amount; };}
var add2 = createAdder(2);
add2(2); //4add2(8); //10
var add3 = createAdder(3);
add3(3); //6add3(7); //10
Closures
(function(exports, undefined){ //ALL your code here var localVar = "bar" globalVar = "baz"; exports.foo = "bat";})(window);
alert(localVar); //erroralert(globalVar); //"baz"alert(window.globalVar); //"baz"alert(foo); //"bat"alert(window.foo); //"bat"
Module Pattern
BEWARE: export (singular) is a reserved word in Safari
this
this
• Trips everyone up
• Special variable used within a function
• Refers to the “contextual object”
• Changes based on where a function executes
var Foo = { bar: "bar", baz: function() { return this.bar; }};
Foo.baz(); //"bar"
Foo.bar = "bat";Foo.baz(); //"bat"
var baz = Foo.baz;baz(); //undefined
this
var Foo = { bar: "bar", baz: function() { return this.bar; }};
Foo.bat = function() { return this.bar + "bat";};
Foo.bat(); //"barbat"
this
call & apply
• Methods in the function prototype
• Change the context in which a function executes!
var Foo = { bar: "bar", baz = function(param1, param2) { return this.bar + param1 + param2; }};
var Foo2 = { bar: "123"};
Foo.baz("baz", "bat"); //"barbazbat"
Foo.baz.apply(Foo2, "baz", "bat"); //"123bazbat"Foo.baz.call(Foo2, ["baz", "bat"]); //"123bazbat"
call & apply
Exceptions
Exceptions
• All errors are thrown
• Classic try...catch...finally blocks
try { funcDoesNotExist();} catch (e) { alert(e); //ReferenceError: funcDoesNotExist is not defined} finally { //Always Executes}
Exceptions
function Foo() { throw new Error("Message");}
function Bar() { throw "Message";}
try { Foo();} catch (e) { e.message == "Message"; //true}
try { Bar();} catch (e) { e == "Message"; //true}
Exceptions
Prototype
OOP... Kinda...
• Almost no real difference between a dictionary and an object
• Named Functions double as object constructors
• Function objects contain a prototype dictionary that is copied to instance when using new
Foo‣bar‣prototype‣baz‣constructor‣__proto__
function Foo() { //The "Constructor"}
Foo.bar = function() { //A "Static" Function}
Foo.prototype.baz = function() { //A "Method"};
OOP... Kinda...
instance‣__proto__‣baz‣constructor‣__proto__‣...
var instance = new Foo();
instance.baz(); //worksinstance.bar(); //error
Foo.bar(); //worksFoo.baz(); //errorFoo.prototype.baz(); //works
new
instance‣bat‣__proto__‣baz‣constructor‣__proto__‣...
instance.bat = function() { /* ... */ }
instance.bat(); //works
Foo.bat(); //errorFoo.prototype.bat(); //error
new
function Foo(baz) { this.baz = baz;}
Foo.prototype.bar = function() { return this.baz;};
var foo1 = new Foo(1);var foo2 = new Foo(2);
foo1.bar(); //1foo2.bar(); //2
Foo.prototype.bar = function() { return this.baz * 2;};
foo1.bar(); //2foo2.bar(); //4
Overriding Prototype
Asynchronous
Asynchronous
• setTimeout, setInterval allow you to have code executing asynchronously while other code executes
var id = setInterval(function() { //Code to execute every 1000 milliseconds}, 1000);
//clearInterval(id); to stop
setInterval
var id = setTimeout(function() { //Code to execute after 1000 milliseconds have passed}, 1000);
//clearTimeout(id); to cancel
setTimeout
setTimeout(function() { //Code to run in parallel //while the code after is //executed.}, 1);
//Code here will execute immediately//without waiting on the above
Nifty Trick
DOM
DOM
• Document Object Model
• API to interact with the HTML/XHTML document
var paragraph = document.createElement('p');var content = document.createTextNode("Lorem Ipsum");
paragraph.appendChild(content);paragraph.classList.add('my-class');
document.getElementsByTagName('body')[0].appendChild(paragraph);
DOM
JSON
JSON
Douglas CrockfordAwesome
2001
JSON
• JavaScript Object Notation
• Serialization format that is basically JavaScript code minus comments
• Can be eval()’ed
• Minimal overhead compared to XML
• No advanced parsers needed
{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] }}}
JSON<menu id="file" value="File"> <popup> <menuitem value="New" onclick="CreateNewDoc()" /> <menuitem value="Open" onclick="OpenDoc()" /> <menuitem value="Close" onclick="CloseDoc()" /> </popup></menu>
jQuery
jQuery
John ResigAuthor, jQuery
January 2006
jQuery
• Cross-browser JavaScript library
• Simplifies and normalizes DOM, AJAX, etc.
• Centers around using extended CSS selectors to grab an element(s)
Find all div tagsAdd class special
$("div").addClass("special");
jQuery
$("#foo") .html("<strong>bar</strong> baz");
jQuery<div id="foo"></div>
<div id="foo"> <strong>bar</strong> baz</div>
•Hide all images with the class preview•When element with the class button is clicked, show all images with the class preview
$('img.preview').hide();$('.button').click(function(){ $('img.preview').show();});
jQuery
When .button is clicked, fade out img.preview over 600 milliseconds and then remove it from the DOM
$('.button').click(function(){ $('img.preview') .fadeOut(600, function() { $(this).remove(); });});
Animation
Events
• jQuery wraps an event handling system
• Handles browser events, AJAX events, and custom events
$(document).ready(function() { //Only execute when the document fires //its onready event (page is done loading)});
$(document).bind('ready', function() { //Equivalent to the above});
Events
$('img').hover(function(){ //Do something when user hovers over //any img tag});
Events
AJAX
• Asynchronous JavaScript And XML
• Though never use XML, use JSON
• jQuery has an AJAX library
• Wraps all the different browser quirks
• IE is weird
$.ajax({ url: "test.php", success: function(data){ $('div.status').addClass("done") .html(data); }});
AJAX
Tools
Chrome/Safari Devel. Tools
Firefox FireBug