Intro
Grammar
Objects
Functions
Inheritance
Arrays
. [] ( ) Refinement and invocation
delete new typeof + - ! Unary operators
* / % Multiplication, division, modulo
+ - Addition/concatenation, subtraction
>= <= > < Inequality
=== !== Equality
&& Logical and
|| Logical or
?: Ternary
var empty_object = {};
var stooge = {
"first-name": "Jerome",
"last-name": "Howard"
};
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
stooge["first-name"] // "Joe"
stooge["middle-name"] // undefined
flight.status // undefined
stooge["FIRST-NAME"] // undefined
var middle = stooge["middle-name"] || "(none)";
var status = flight.status || "unknown";
flight.equipment // undefined
flight.equipment.model // throw "TypeError"
flight.equipment && flight.equipment.model // undefined
stooge['first-name'] = 'Jerome';
// If the object does not already have that property name, the object is augmented:
stooge['middle-name'] = 'Lester';
stooge.nickname = 'Curly';
flight.equipment = {
model: 'Boeing 777'
};
flight.status = 'overdue';
var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname;
// nick is 'Curly' because x and stooge
// are references to the same object
var a = {}, b = {}, c = {};
// a, b, and c each refer to a
// different empty object
a = b = c = {};
// a, b, and c all refer to
// the same empty object
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
var another_stooge = Object.create(stooge);
another_stooge['first-name'] = 'Harry';
another_stooge['middle-name'] = 'Moses';
another_stooge.nickname = 'Moe';
stooge.profession = 'actor';
another_stooge.profession // 'actor'
typeof flight.number // 'number'
typeof flight.status // 'string'
typeof flight.arrival // 'object'
typeof flight.manifest // 'undefined'
typeof flight.toString // 'function'
typeof flight.constructor // 'function'
// typeof consideres the whole prototype chain
// hasOwnProperty checks own object
flight.hasOwnProperty('number') // true
flight.hasOwnProperty('constructor') // false
another_stooge.nickname // 'Moe'
// Remove nickname from another_stooge, revealing
// the nickname of the prototype.
delete another_stooge.nickname;
another_stooge.nickname // 'Curly'
// Create a variable called add and store a function
// in it that adds two numbers.
var add = function (a, b) {
return a + b;
};
// Create myObject. It has a value and an increment
// method. The increment method takes an optional
// parameter. If the argument is not a number, then 1
// is used as the default.
var myObject = {
value: 0,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment( );
document.writeln(myObject.value); // 1
myObject.increment(2);
document.writeln(myObject.value); // 3
var sum = add(3, 4);
// Augment myObject with a double method.
myObject.double = function() {
var that = this; // Workaround.
var helper = function() {
that.value = add(that.value, that.value);
};
helper(); // Invoke helper as a function.
};
// Invoke double as a method.
myObject.double();
document.writeln(myObject.getValue( )); // 6
// Create a constructor function called Quo.
// It makes an object with a status property.
var Quo = function (string) {
this.status = string;
};
// Give all instances of Quo a public method
// called get_status.
Quo.prototype.get_status = function ( ) {
return this.status;
};
// Make an instance of Quo.
var myQuo = new Quo("confused");
document.writeln(myQuo.get_status( )); // confused
// Make an array of 2 numbers and add them.
var array = [3, 4];
var sum = add.apply(null, array); // sum is 7
// Make an object with a status member.
var statusObject = {
status: 'A-OK'
};
// statusObject does not inherit from Quo.prototype,
// but we can invoke the get_status method on
// statusObject even though statusObject does not have
// a get_status method.
var status = Quo.prototype.get_status.apply(statusObject);
// status is 'A-OK'
var sum = function ( ) {
var i, sum = 0;
for (i = 0; i < arguments.length; i += 1) {
sum += arguments[i];
}
return sum;
};
document.writeln(sum(4, 8, 15, 16, 23, 42)); // 108
var add = function (a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw {
name: 'TypeError',
message: 'add needs numbers'
};
}
return a + b;
}
// Make a try_it function that calls the new add function incorrectly.
var try_it = function () {
try {
add("seven");
} catch (e) {
document.writeln(e.name + ': ' + e.message);
}
}
try_it();
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
var hanoi = function (disc, src, aux, dst) {
if (disc > 0) {
hanoi(disc - 1, src, dst, aux);
document.writeln('Move disc ' + disc +
' from ' + src + ' to ' + dst);
hanoi(disc - 1, aux, src, dst);
}
};
hanoi(3, 'Src', 'Aux', 'Dst');
var foo = function () {
var a = 3, b = 5;
var bar = function () {
var b = 7, c = 11;
// At this point, a is 3, b is 7, and c is 11
a += b + c;
// At this point, a is 21, b is 7, and c is 11
};
// At this point, a is 3, b is 5, and c is not defined bar();
// At this point, a is 21, b is 5
};
var myObject = function () {
var value = 0;
return {
increment: function (inc) {
value += typeof inc === 'number' ? inc : 1;
},
getValue: function () {
return value;
}
};
}();
// sync - client is blocked
request = prepare_the_request();
response = send_request_synchronously(request);
display(response);
// async
request = prepare_the_request();
send_request_asynchronously(request, function (response) {
display(response);
});
getElement('myBoxDiv').
move(350, 150).
width(100).
height(100).
color('red').
border('10px outset').
padding('4px').
appendText("Please stand by").
on('mousedown', function (m) {
this.startDrag(m, this.getNinth(m));
}).
on('mousemove', 'drag').
on('mouseup', 'stopDrag').
later(2000, function () {
this.color('yellow').
setHTML("What hath God wraught?").
slide(400, 40, 200, 200);
}).
tip('This box is resizeable');
var Mammal = function (name) {
this.name = name;
};
Mammal.prototype.get_name = function () {
return this.name;
};
Mammal.prototype.says = function () {
return this.saying || '';
};
var myMammal = new Mammal('Herb the Mammal');
var name = myMammal.get_name(); // 'Herb the Mammal'
var Cat = function (name) {
this.name = name;
this.saying = 'meow';
};
// Replace Cat.prototype with a new instance of Mammal
Cat.prototype = new Mammal();
// Augment the new prototype with
// purr and get_name methods.
Cat.prototype.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
Cat.prototype.get_name = function () {
return this.says() + ' ' + this.name + ' ' + this.says();
};
var myCat = new Cat('Henrietta');
var says = myCat.says(); // 'meow'
var purr = myCat.purr(5); // 'r-r-r-r-r'
var name = myCat.get_name(); // 'meow Henrietta meow'
var myObject = maker(f, l, m, c, s);
var myObject = maker({
first: f,
last: l,
state: s,
city: c
});
var myMammal = {
name : 'Herb the Mammal', get_name : function () {
return this.name;
},
says : function () {
return this.saying || '';
}
};
var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
myCat.get_name = function () {
return this.says() + ' ' + this.name + ' ' + this.says();
};
var mammal = function (spec) {
var that = {};
that.get_name = function () {
return spec.name;
};
that.says = function () {
return spec.saying || '';
};
return that;
};
var myMammal = mammal({name: 'Herb'});
var empty = [];
var numbers = [
'zero', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine'
];
empty[1] // undefined
numbers[1] // 'one'
empty.length // 0
numbers.length // 10
var numbers_object = {
'0': 'zero', '1': 'one', '2': 'two',
'3': 'three', '4': 'four', '5': 'five',
'6': 'six', '7': 'seven', '8': 'eight',
'9': 'nine'
};
var misc = [
'string', 98.6, true, false, null, undefined,
['nested', 'array'], {object: true}, NaN,
Infinity
];
misc.length // 10
var myArray = [];
myArray.length // 0
myArray[1000000] = true;
myArray.length // 1000001
numbers.length = 3;
// numbers is ['zero', 'one', 'two']
numbers[numbers.length] = 'shi';
// numbers is ['zero', 'one', 'two', 'shi']
numbers.push('go');
// numbers is ['zero', 'one', 'two', 'shi', 'go']
// numbers is ['zero', 'one', 'two', 'shi', 'go']
delete numbers[2];
// numbers is ['zero', 'one', undefined, 'shi', 'go']
numbers.splice(2, 1);
// numbers is ['zero', 'one', 'shi', 'go']
var i;
for (i = 0; i < myArray.length; i += 1) {
document.writeln(myArray[i]);
}
Array.method('reduce', function (f, value) {
var i;
for (i = 0; i < this.length; i += 1) {
value = f(this[i], value);
}
return value;
});
Array.method('reduce', function (f, value) {
var i;
for (i = 0; i < this.length; i += 1) {
value = f(this[i], value);
}
return value;
});
var data = [4, 8, 15, 16, 23, 42];
var add = function (a, b) {
return a + b;
};
var sum = data.reduce(add, 0); // sum is 108
Array.dim = function (dimension, initial) {
var a = [], i;
for (i = 0; i < dimension; i += 1) {
a[i] = initial;
}
return a;
};
// Make an array containing 10 zeros.
var myArray = Array.dim(10, 0);
var matrix = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
matrix[2][1] // 7
Array.matrix = function (m, n, initial) {
var a, i, j, mat = [];
for (i = 0; i < m; i += 1) {
a = [];
for (j = 0; j < n; j += 1) {
a[j] = initial;
}
mat[i] = a;
}
return mat;
};
JavaScript: The Good Parts
Douglas Crockford
Thank you for your attention!