a re-introduction to javascript
DESCRIPTION
Slides from a tutorial I gave at ETech 2006. Notes to accompany these slides can be found here: http://simonwillison.net/static/2006/js-reintroduction-notes.htmlTRANSCRIPT
![Page 1: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/1.jpg)
1
A (Re)-Introduction to JavaScript
Simon Willison ETech, March 6th, 2005
http://www.flickr.com/photos/tomsly/93947243/ - thomas_sly
1
![Page 2: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/2.jpg)
Coming up...
2
• Numbers, Strings and things
• Variables and Operators
• Control Structures
• Objects and Arrays
• Functions
• Object constructors and inheritance
• Inner functions and closures
• Memory Leaks... and more
2
![Page 3: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/3.jpg)
Book recommendation
• JavaScript: The Definitive Guide
– by David Flanagan
• Comprehensive overview of the language in the first 20 chapters
• New edition out later this year
3
3
![Page 4: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/4.jpg)
More book recommendations
• For practical applications of this stuff:
4
4
![Page 5: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/5.jpg)
You will need...
5
• Firefox
– Any web browser can run JavaScript, but Firefox has the best tools for developers
• Jesse Ruderman's 'shell' tool
– http://www.squarefree.com/shell/
• A text editor may come in handy too
5
![Page 6: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/6.jpg)
In the words of its creator
6
JavaScript was a rushed little hack for Netscape 2 that was then frozen prematurely
during the browser wars, and evolved significantly only once by ECMA. So its early
flaws were never fixed, and worse, no virtuous cycle of fine-grained community
feedback in the form of standard library code construction, and revision of the foundational
parts of the language to better support the standard library and its common use-cases,
ever occurred.http://weblogs.mozillazine.org/roadmap/archives/2006/02/js_and_python_news.html
6
![Page 7: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/7.jpg)
7
(in 30 seconds)
The History of JavaScript
http://www.flickr.com/photos/kingcoyote/93491484/ - King Coyote
7
![Page 8: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/8.jpg)
JavaScript was...
8
Invented by Brendan Eich in 1995 for Netscape; originally called LiveScript, current name being an ill-fated marketing decision to
tie in with Sun's newly released Java; adapted by Microsoft as JScript for IE 3 in
1996; standardised as ECMAScript in 1997; sort-of included in Flash as ActionScript;
updated to ECMAScript 3rd edition in 1998
8
![Page 9: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/9.jpg)
Not quite general purpose
• No direct concept of input or output
• Runs within a host environment
– Web browser
– Adobe Acrobat
– Photoshop
– Windows Scripting Host
– Yahoo! Widget Engine
– and more...
9
9
![Page 10: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/10.jpg)
Syntax
http://www.flickr.com/photos/olivepress/11223013/ - Brian Sawyer
10
![Page 11: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/11.jpg)
Reserved words
break else new var case finally return void catch for switch while
continue function this with default if throw delete in try
do instanceof typeof
abstract enum int short boolean export interface static
byte extends long super char final native synchronized
class float package throws const goto private transient
debugger implements protected volatile double import public
11
11
![Page 12: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/12.jpg)
Style recommendations
• Avoid semi-colon insertion like the plague
; ; ; friends• Declare variables religiously with 'var'
• Global variables are evil. Avoid them if you can.
• Indent consistently
12
12
![Page 13: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/13.jpg)
13
Types
http://www.flickr.com/photos/kvitsh/64919318/ - K'vitsh / Heather Hutchinson
13
![Page 14: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/14.jpg)
JavaScript types
14
• Numbers
• Strings
• Booleans
• Functions
• Objects
14
![Page 15: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/15.jpg)
JavaScript types (improved)
• Number
• String
• Boolean
• Object– Function
– Array
– Date
– RegExp
• Null
• Undefined15
15
![Page 16: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/16.jpg)
16
Numbers
http://www.flickr.com/photos/51035555243@N01/72778694/ - Thomas Hawk
16
![Page 17: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/17.jpg)
Numbers
17
• "double-precision 64-bit format IEEE 754 values"
• No such thing as an integer
0.1 + 0.2 = 0.30000000000000004
3 + 5.3
28 % 6 etc...
• Math namespace for advanced operations
17
![Page 18: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/18.jpg)
Math stuff
• Math.PI, Math.E, Math.LN10, Math.LN2, Math.LOG10E, Math.SQRT1_2, Math.SQRT2
• Math.abs(x), Math.acos(x), Math.asin(x), Math.atan(x), Math.atan2(y, x), Math.ceil(x), Math.cos(x), Math.exp(x), Math.floor(x), Math.log(x), Math.max(x, ..), Math.min(x, ..), Math.pow(x, y), Math.random(), Math.round(x), Math.sin(x), Math.sqrt(x), Math.tan(x)
18
18
![Page 19: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/19.jpg)
parseInt (and parseFloat)
• parseInt converts a string to a number
> parseInt("123");123> parseInt("010");8
• !?
> parseInt("010", 10);10> parseInt("11", 2)3
19
Always specify the base
19
![Page 20: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/20.jpg)
NaN and Infinity
> parseInt("hello", 10)NaN
• NaN is toxic
> NaN + 5NaN> isNaN(NaN)true
• Special values for Infinity and -Infinity:
> 1 / 0Infinity
20
> -1 / 0-Infinity
20
![Page 21: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/21.jpg)
21
Strings
http://www.flickr.com/photos/solarider/53494967/ - solarider
21
![Page 22: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/22.jpg)
Strings
22
• Sequences of characters
• Sequences of unicode characters (16 bit)
"\u0020"
• A character is a string of length 1
> "hello".length
5
• Strings are objects!
22
![Page 23: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/23.jpg)
String methods
> "hello".charAt(0)
h
> "hello, world".replace("hello", "goodbye")
goodbye, world
> "hello".toUpperCase()
HELLO
23
23
![Page 24: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/24.jpg)
More string methods
s.charAt(pos) s.charCodeAt(pos)
s.concat(s1, ..)
s.indexOf(s1, start)
s.lastIndexOf(s1, startPos) s.localeCompare(s1) s.match(re)
s.replace(search, replace)
s.search(re) s.slice(start, end) s.split(separator, limit)
s.substring(start, end) s.toLowerCase() s.toLocaleLowerCase() s.toUpperCase() s.toLocaleUpperCase()
24
24
![Page 25: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/25.jpg)
Null and undefined
• null = deliberately no value
• undefined = no value assigned yet
– Variables declared but not initialised
– Object/array members that don't exist
25
25
![Page 26: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/26.jpg)
Booleans
• Boolean type: true or false
• Everything else is "truthy" or "falsy"
• 0, "", NaN, null, undefined are falsy
• Everything else is truthy
• Boolean operations: &&, || and !
• Convert any value to it's boolean equivalent by applying not twice:
> !!""
false26
> !!234
true
26
![Page 27: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/27.jpg)
27
Variables and operators
http://www.flickr.com/photos/antmoose/71277315/ - antmoose / Anthony M.
27
![Page 28: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/28.jpg)
Variable declaration
28
• New variables in JavaScript are declared using the var keyword:
var a;
var name = "simon";
• If you declare a variable without assigning it to anything, its value is undefined.
If you forget the var, you get a global
variable. Never, ever do this - not even if you mean it.
28
![Page 29: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/29.jpg)
Operators
Numeric operators: +, -, *, / and %
• Compound assignment operators:
+=, -=, *=, /=, %=
• Increment and decrement:
a++, ++a, b--, --b
• String concatenation:
> "hello" + " world"
hello world29
29
![Page 30: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/30.jpg)
Type coercion
> "3" + 4 + 5
345
> 3 + 4 + "5"
75
• Adding an empty string to something else converts it to a string.
30
30
![Page 31: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/31.jpg)
Comparison
• >, <, >=, <= work for numbers and strings
• Equality tests use == and != ... sort of> "dog" == "dog"true> 1 == truetrue
• === and !== avoid type coercion> 1 === truefalse> true === truetrue
31
31
![Page 32: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/32.jpg)
The typeof operator
typeof v
32
number 'number'
string 'string'
boolean 'boolean'
function 'function'
object 'object'
array 'object'
null 'object'
undefined 'undefined'
32
![Page 33: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/33.jpg)
33
Control structures
http://www.flickr.com/photos/setre/8825214/ - setre
33
![Page 34: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/34.jpg)
if statements
34
var name = "kittens";
if (name == "puppies") {
name += "!";
} else if (name == "kittens") {
name += "!!";
} else {
name = "!" + name;
}
name == "kittens!!"
34
![Page 35: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/35.jpg)
while and do-while
while (true) {
// an infinite loop!
}
do {
var input = get_input();
} while (inputIsNotValid(input))
35
35
![Page 36: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/36.jpg)
for loops
for (var i = 0; i < 5; i++) { // Will execute 5 times}
36
36
![Page 37: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/37.jpg)
switch statement
• Multiple branches depending on a number or string
switch(action) { case 'draw': drawit(); break; case 'eat': eatit(); break; default: donothing();}
37
37
![Page 38: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/38.jpg)
fall through
switch(a) { case 1: // fallthrough case 2: eatit(); break; default: donothing();}
• Deliberate labelling of fall through is good practise
38
38
![Page 39: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/39.jpg)
Switch expressions
• Expressions are allowed
• Comparisons take place using ===
switch(1 + 3):
case 2 + 2:
yay();
break; default:
neverhappens();
}
39
39
![Page 40: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/40.jpg)
Short-circuit logic
• The && and || operators use short-circuit logic: they will execute their second operand dependant on the first.
• This is useful for checking for null objects before accessing their attributes:
var name = o && o.getName();
• Or for setting default values:
var name = otherName || "default";
40
40
![Page 41: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/41.jpg)
The tertiary operator
• One-line conditional statements
var ok = (age > 18) ? "yes" : "no";
• Easy to abuse; use with caution
41
41
![Page 42: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/42.jpg)
Exceptions
try { // Statements in which // exceptions might be thrown} catch(error) { // Statements that execute // in the event of an exception} finally { // Statements that execute // afterward either way}
throw new Error("An error!");throw "Another error!";
42
42
![Page 43: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/43.jpg)
43
Objects
http://www.flickr.com/photos/spengler/51617271/ - Andreas D.
43
![Page 44: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/44.jpg)
Objects
44
• Simple name-value pairs, as seen in:
– Dictionaries in Python
– Hashes in Perl and Ruby
– Hash tables in C and C++
– HashMaps in Java
– Associative arrays in PHP
• Very common, versatile data structure
• Name part is a string; value can be anything
44
![Page 45: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/45.jpg)
Basic object creation
var obj = new Object();
• Or:
var obj = {};
• These are semantically equivalent; the second is called object literal syntax and is more convenient.
45
45
![Page 46: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/46.jpg)
Property access
obj.name = "Simon"
var name = obj.name;
• Or...
obj["name"] = "Simon";
var name = obj["name"];
• Semantically equivalent; the second uses strings so can be decided at run-time (and can be used for reserved words)
46
46
![Page 47: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/47.jpg)
Object literal syntax
var obj = { name: "Carrot", "for": "Max", details: { color: "orange", size: 12 }}
> obj.details.colororange
47
> obj["details"]["size"]
12
47
![Page 48: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/48.jpg)
for (var attr in obj)
• You can iterate over the keys of an object:
var obj = { 'name': 'Simon', 'age': 25};
for (var attr in obj) {
print (attr + ' = ' + obj[attr]);
}
• Don't attempt this with arrays (coming up next). There are safer ways of iterating over them.
48
48
![Page 49: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/49.jpg)
49
Arrays
http://www.flickr.com/photos/adrian_s/28567268/ - waffler / Adrian Sampson
49
![Page 50: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/50.jpg)
Arrays
50
• A special type of object: Keys are whole numbers, not strings.
• Use [] syntax, just like objects
> var a = new Array();
> a[0] = "dog";
> a[1] = "cat";
> a[2] = "hen";
> a.length
3
50
![Page 51: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/51.jpg)
Array literals
• More convenient notation:
> var a = ["dog", "cat", "hen"];
> a.length
3
51
51
![Page 52: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/52.jpg)
array.length
> var a = ["dog", "cat", "hen"];
> a[100] = "fox";
> a.length
101
typeof a[90] == 'undefined'
• array.length is always one more than the highest index
• The safest way to append new items is:
a[a.length] = item;52
52
![Page 53: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/53.jpg)
Array iteration
for (var i = 0; i < a.length; i++) {
// Do something with a[i]
}
• Improve this by caching a.length at start:
for (var i = 0, j = a.length; i < j; i++) {
// Do something with a[i]
}53
53
![Page 54: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/54.jpg)
Even better iteration
for (var i = 0, item; item = a[i]; i++) {
// Do something with item
}
• This trick only works with arrays that are known not to contain falsy values. The following array will break with the above idiom:
var a = [10, "dog", false, "elephant"];
• (Yes, you can have mixed content in arrays)
54
54
![Page 55: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/55.jpg)
Array methods
a.toString(), a.toLocaleString(),a.concat(item, ..), a.join(sep), a.pop(), a.push(item, ..), a.reverse(), a.shift(),
a.slice(start, end), a.sort(cmpfn), a.splice(start, delcount, [item]..),
a.unshift([item]..)
55
55
![Page 56: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/56.jpg)
-4.8 -4 -3.2 -2.4 -1.6 -0.8 0 0.8 1.6 2.4 3.2 4 4.8
-3.2
-2.4
-1.6
-0.8
0.8
1.6
2.4
3.2
56
Functions
56
![Page 57: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/57.jpg)
Functions
57
• Don't get much simpler than this:
function add(x, y) {
var total = x + y;
return total;
}
• If nothing is explicitly returned, return value is undefined
57
![Page 58: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/58.jpg)
Arguments
• Parameters: "They're more like... guidelines"
• Missing parameters are treated as undefined:
> add()
Nan // addition on undefined
• You can pass in more arguments than expected:
> add(2, 3, 4)5 // added the first two; 4 was ignored
• How is this behaviour useful?58
58
![Page 59: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/59.jpg)
arguments
• The arguments special variable provides access to arguments as an array-like object
function add() { var sum = 0; for (var i = 0, j = arguments.length; i < j; i++) { sum += arguments[i]; } return sum;}
> add(2, 3, 4, 5)14
59
59
![Page 60: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/60.jpg)
avg()
• More useful: an averaging function:
function avg() {
var sum = 0;
for (var i = 0, j = arguments.length;
i < j; i++) {
sum += arguments[i];
}
return sum / arguments.length;
}
60
60
![Page 61: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/61.jpg)
Averaging an array?
• Our fancy multi-argument function isn't much good if our data is already in an array. Do we have to rewrite it?
function avgArray(arr) { var sum = 0; for (var i = 0, j = arr.length; i < j; i++) { sum += arguments[i]; } return sum / arr.length;
}
61
61
![Page 62: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/62.jpg)
Using avg() with an array
• That's not necessary:
> avg.apply(null, [2, 3, 4, 5])
3.5
• Functions are objects with methods too!
• The apply method takes an array of argments as the second argument...
• We'll find out about the first argument a little later
62
62
![Page 63: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/63.jpg)
Anonymous functions
• The following is semantically equivalent to our earlier avg() function:
var avg = function() {
var sum = 0;
for (var i = 0, j = arguments.length;
i < j; i++) {
sum += arguments[i];
}
return sum / arguments.length;
}
63
63
![Page 64: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/64.jpg)
The block scope trick
• Block scope is a feature of C where every set of braces defines a new scope. It can be simulated in JavaScript:
var a = 1;var b = 2;(function() { var b = 3; a += b;})();> a4> b2
64
64
![Page 65: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/65.jpg)
Recursive functions
function countChars(elm) {
if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child;
child = elm.childNodes[i]; i++) {
count += countChars(child);
}
return count;
}
65
65
![Page 66: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/66.jpg)
arguments.callee
• arguments.callee is the current function:var charsInBody = (function(elm) {
if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child;
child = elm.childNodes[i]; i++) {
count += arguments.callee(child);
}
return count;
})(document.body);66
66
![Page 67: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/67.jpg)
arguments.callee to save state
• This function remembers how many times it has been called:
function counter() { if (!arguments.callee.count) { arguments.callee.count = 0; } return arguments.callee.count++;}> counter()0> counter()1
67
67
![Page 68: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/68.jpg)
68
Constructors
http://www.flickr.com/photos/45339031@N00/100472474/ - piccadillywilson / Matt
68
![Page 69: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/69.jpg)
Functions and objects
69
function makePerson(first, last) { return { first: first, last: last }}function personFullName(person) { return person.first + ' ' + person.last;}function personFullNameReversed(person) { return person.last + ', ' + person.first}
69
![Page 70: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/70.jpg)
Functions and objects (II)
> s = makePerson("Simon", "Willison");
> personFullName(s)
Simon Willison
> personFullNameReversed(s)
Willison, Simon
• Surely we can attach functions to the objects themselves?
70
70
![Page 71: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/71.jpg)
Methods, first try
function makePerson(first, last) { return { first: first, last: last, fullName: function() { return this.first + ' ' + this.last; }, fullNameReversed: function() { return this.last + ', ' + this.first; } }}
71
71
![Page 72: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/72.jpg)
Using methods
> s = makePerson("Simon", "Willison")
> s.fullName()
Simon Willison
> s.fullNameReversed()
Willison, Simon
72
72
![Page 73: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/73.jpg)
dot notation is required
> s = makePerson("Simon", "Willison")
> var fullName = s.fullName;
> fullName()
undefined undefined
• If you call a function without using dot notation, 'this' is set to the global object. In the browser, this is the same as 'window'.
73
73
![Page 74: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/74.jpg)
Constructors
function Person(first, last) { this.first = first; this.last = last; this.fullName = function() { return this.first + ' ' + this.last; } this.fullNameReversed = function() { return this.last + ', ' + this.first; }}
var s = new Person("Simon", "Willison");
74
74
![Page 75: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/75.jpg)
new
• 'new' creates a new empty object and calls the specified function with 'this' set to that object.
• These constructor functions should be Capitalised, as a reminder that they are designed to be called using 'new'
• This is key to understanding JavaScript's object model
75
75
![Page 76: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/76.jpg)
Sharing methods
function personFullName() { return this.first + ' ' + this.last;}function personFullNameReversed() { return this.last + ', ' + this.first;}function Person(first, last) { this.first = first; this.last = last; this.fullName = personFullName; this.fullNameReversed = personFullNameReversed;}
76
76
![Page 77: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/77.jpg)
Person.prototype
function Person(first, last) { this.first = first; this.last = last;}Person.prototype.fullName = function() { return this.first + ' ' + this.last;}Person.prototype.fullNameReversed = function() { return this.last + ', ' + this.first;}
77
77
![Page 78: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/78.jpg)
instanceof
• The instanceof operator can be used to test the type of an object, based on its constructor (and prototype hierarchy, explained in the next section).
var a = [1, 2, 3];a instanceof Arraytruea instanceof Objecttruea instanceof Stringfalse
78
78
![Page 79: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/79.jpg)
79
Inheritance
http://www.flickr.com/photos/bingolittle/5803243/ - Bingo Little
79
![Page 80: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/80.jpg)
Adding to an existing set of objects
> s = new Person("Simon", "Willison");> s.firstNameCaps();TypeError on line 1:
s.firstNameCaps is not a function
> Person.prototype.firstNameCaps = function() { return this.first.toUpperCase()}> s.firstNameCaps()SIMON
80
80
![Page 81: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/81.jpg)
Extending core objects
> var s = "Simon";> s.reversed()TypeError: s.reversed is not a function
> String.prototype.reversed = function() { var r = ''; for (var i = this.length - 1; i >= 0; i--){ r += this[i]; } return r;}> s.reversed()nomiS> "This can now be reversed".reversed()
desrever eb won nac sihT81
81
![Page 82: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/82.jpg)
Object.prototype
• All prototype chains terminate at Object.prototype
• Its methods include toString(), which we can over-ride:> var s = new Person("Simon", "Willison");> s[object Object]> Person.prototype.toString = function() { return '<Person: ' + this.fullName() + '>';}> s<Person: Simon Willison>
82
82
![Page 83: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/83.jpg)
Perils of modifying Object.prototype
• Remember for (var attr in obj)?
• It will include stuff that's been newly added to Object.prototype
• This stupid behaviour is sadly baked in to the language
• Some libraries (Prototype is a prime offender) do it anyway
83
83
![Page 84: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/84.jpg)
So what about inheritance?
• Problem: JavaScript is a prototype-based language, but it pretends to be a class-based language
• As a result, it doesn't do either very well
• Inheritance doesn't quite behave how you would expect
84
84
![Page 85: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/85.jpg)
Here's a special kind of person
function Geek() { Person.apply(this, arguments); this.geekLevel = 5;}Geek.prototype = new Person();Geek.prototype.setLevel = function(lvl) { this.geekLevel = lvl;}Geek.prototype.getLevel = function() { return this.geekLevel;}> s = new Geek("Simon", "Willison")> s.fullName()Simon Willison> s.getLevel()5
85
85
![Page 86: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/86.jpg)
new Person()?
• We're using an instance of the Person object as our prototype
• We have to do this, because we need to be able to modify our prototype to add new methods that are only available to Geek instances
• This is counter-intuitive and, well, a bit dumb
86
86
![Page 87: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/87.jpg)
Solutions?
• Design classes with inheritance in mind - don't do anything important in the constructor (that might break if you create an empty instance for use as a prototype)
• Use one of the many workarounds
– Prototype's Class.create()
– The stuff you get by searching for "javascript inheritance" on the Web
87
87
![Page 88: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/88.jpg)
88
Higher order functions
http://en.wikipedia.org/wiki/Image:Torres_Petronas_Mayo_2004.jpg Ángel Riesgo Martínez
88
![Page 89: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/89.jpg)
Functions are first-class objects
• In English...
– A function is just another object
– You can store it in a variable
– You can pass it to another function
– You can return it from a function
89
89
![Page 90: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/90.jpg)
VAT
VAT is England's national sales tax - 17.5%
var prices = [10, 8, 9.50];
var pricesVat = [];
for (var i = 0; i < prices.length; i++) {
pricesVat[i] = prices[i] * 1.175;
}
90
90
![Page 91: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/91.jpg)
arrayMap
function arrayMap(array, func) {
var result = [];
for (var i = 0; i < array.length; i++) {
result[i] = func(array[i]);
}
return result;
}
function calcVat(price) {
return price * 1.175;
}
var prices = [10, 8, 9.50];
pricesVat = arrayMap(prices, calcVat);
91
91
![Page 92: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/92.jpg)
salesTaxFactory
What if we want to calculate sales tax at 4%?
function salesTaxFactory(percent) {
function func(price) {
return price + (percent / 100) * price;
}
return func;
}
calcVat = salesTaxFactory(17.5);
calc4 = salesTaxFactory(4);
pricesVat = arrayMap(prices, calcVat);
prices4 = arrayMay(prices, calc4);
92
92
![Page 93: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/93.jpg)
An operation factory
function makeOp(op, y) { switch (op) { case '+': return function(x) { return x + y }; case '-': return function(x) { return x - y }; case '/': return function(x) { return x / y }; case '*': return function(x) { return x * y }; default: return function(x) { return x }; }}var third = makeOp('/', 3);var dbl = makeOp('*', 2);print(third(24));print(dbl(5));
93
93
![Page 94: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/94.jpg)
Closures
• The previous code was an example of closures in action
• A closure is a function that has captured the scope in which it was defined
• Actually, functions in JavaScript have a scope chain (similar to the prototype chain)
94
94
![Page 95: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/95.jpg)
What does this do?
95
function openLinksInNewWindows() {
for (var i = 0; i < document.links.length; i++) {
document.links[i].onclick = function() {
window.open(document.links[i].href);
return false;
}
}
}
• The onclick function is a closure which refers back to the original scope; it does NOT retain a copy of the i variable at the time the function was created. By the time the onclick function is executed, i will be the last value assigned by the loop.
95
![Page 96: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/96.jpg)
96
Singleton
http://www.flickr.com/photos/iboy_daniel/90450551/ - iboy_daniel / doug wilson
96
![Page 97: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/97.jpg)
Namespace pollution
97
• JavaScript shares a single global namespace
• It’s easy to clobber other people’s functions and variables
• It’s easy for other people to clobber yours
• The less code affecting the global namespace the better
97
![Page 98: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/98.jpg)
The singleton pattern
var simon = (function() { var myVar = 5; // Private variable function init(x) { // ... can access myVar and doPrivate } function doPrivate(x) { // ... invisible to the outside world } function doSomething(x, y) { // ... can access myVar and doPrivate } return { 'init': init, 'doSomething': doSomething }})();
simon.init(x);
98
98
![Page 99: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/99.jpg)
Singleton benefits
• Singleton lets you wrap up a complex application with dozens of functions up in a single, private namespace - a closure
• This lets you expose only the functions that make up your application's external interface
99
99
![Page 100: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/100.jpg)
Memory leaks
100
http://www.flickr.com/photos/lunchtimemama/97685471/ - lunchtimemama / Scott
100
![Page 101: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/101.jpg)
Internet Explorer sucks
101
• To understand memory leaks, you have to understand a bit about garbage collection
• Stuff gets freed up automatically when it is no longer in use (both JavaScript objects and host objects, such as DOM nodes)
• IE uses different garbage collectors for JS and for the DOM, and can't handle circular references between them
101
![Page 102: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/102.jpg)
This leaks
function leak() {
var div = document.getElementById('d');
div.obj = {
'leak': div
}
}
• Call it enough times and IE will crash
102
102
![Page 103: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/103.jpg)
This also leaks
function sneakyLeak() {
var div = document.getElementById('d');
div.onclick = function() {
alert("hi!");
}
}
• Why? Spot the closure!
103
103
![Page 104: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/104.jpg)
Difficulties
• These things can be very hard to detect - especially in large, complex applications where a cycle might occur over many nodes and JavaScript objects
• One solution:function noLeak() {
var div = document.getElementById('d');
div.onclick = function() {
alert("hi!");
}
div = null;
}
104
104
![Page 105: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/105.jpg)
More solutions
• Most popular JavaScript libraries have systems for attaching and detaching events
• Many of these can automatically free event references when the page is unloaded
• Use these, but always be aware of the problem
105
105
![Page 106: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/106.jpg)
106
Performance
http://www.flickr.com/photos/javic/100567276/ - javic
106
![Page 107: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/107.jpg)
Performance tips
107
• De-reference complex lookupsvar s = document.getElementById('d').style;
s.width = '100%';
s.color = 'red';
// ...
s.display = 'block';
• ... especially inside loops
var lookup = foo.bar.bav;
for (var i = 0; i < 1000; i++) {
lookup.counter += someCalc();
}
107
![Page 108: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/108.jpg)
108
Libraries
http://www.flickr.com/photos/klara/94704029/ - klara(!) / klara
108
![Page 109: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/109.jpg)
Suggested libraries
109
¯¯dojotoolkit.org
developer.yahoo.net/yui/
mochikit.com
prototype.conio.net
script.aculo.us
109
![Page 110: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/110.jpg)
Tell Alex I told you this...
110
• Everything in JavaScript is an Object. Even functions
• Every object is always mutable
• The dot operator is equivalent to de-referencing by hash (e.g., foo.bar === foo["bar"])
• The new keyword creates an object that class constructors run inside of, thereby imprinting them
• Functions are always closures (combine w/ previous rule to create OOP)
• The this keyword is relative to the execution context, not the declaration context
• The prototype property is mutable
110
![Page 111: A Re-Introduction to JavaScript](https://reader033.vdocument.in/reader033/viewer/2022052700/5549408db4c9050a4d8b50a8/html5/thumbnails/111.jpg)
111
Thank you!
http://www.flickr.com/photos/nataliedowne/14517351/ - NatBat / Natalie Downe
111