Understanding the environment

Global objects - types

Array

var foo = new Array();
var foo = new Array(10);
var foo = new Array('a', 'b', 'c');
var foo = [];
var foo = Array(5);
foo[999] = 'large array';

Boolean

var asFunction = Boolean(false); // == false
var asConstructor = new Boolean(false); // == true
var isFalse =  !'false';
var isTrue  = !!'false';

Date

var date = new Date();
var date = new Date(1234567890);
var date = new Date('December 25, 1995');
var date = new Date(1995, 11, 25);

Function

var sum = new Function('a', 'b', 'return a + b;');
var sum = function(a, b) { return a + b; };
function sum(a, b) { return a + b; }

Number

var num = new Number('5.2');
var num = Number('5.2');
var num = 5.2;

Object

var obj = new Object();
var obj = {};

obj.foo = 'bar';
obj['foo'] = 'bar';

RegExp

var re = new RegExp('foo', 'i');
var re = /foo/i;

/bar/i.test('fooBARbaz'); // true
/bar/i.exec('fooBARbaz'); // ["BAR"]

String

var str = new String('string');
var str = String('string');
var str = 'string';
var str = 'string';
str.replace('i', 'o'); // strong
alert(str); // string

Checking types

if ("foo".constructor == String) {
	alert("is a string");
}

if (typeof "foo" == "string") {
	alert("is a string");
}

Checking types

if (Object.prototype.toString.call("foo")
	== "[object String]") {
	alert("is a string");
}

if ("foo".substr) {
	alert("is a string");
}

Checking types

Variable scope

Exceptions

try {
	window.missingFunction();
} catch (e) {
	alert(e.message);
}

Exceptions

try {
	throw "something went wrong";
} catch (e) {
	alert(e);
}

Understanding the DOM

Traversing and modifying the DOM

Extending the DOM

document.body.prependChild = function(newChild) {
	if (this.childNodes.length) {
		this.insertBefore(newChild, this.firstChild);
	} else {
		this.appendChild(newChild);
	}
};

Extending the DOM

document.body.prependChild = function(newChild) {
	this.insertBefore(newChild, this.firstChild);
};
<div><p id="foo">foo<⁄p></div>
<div><p id="bar">bar<⁄p></div>
<div><p id="baz">baz<⁄p></div>
var foo = document.getElementById('foo');
var bar = document.getElementById('bar');
foo.insertBefore(bar);

Extending the DOM

Extending the DOM

function prependChild(elem, newChild) {
	elem.insertBefore(newChild, elem.firstChild);
}
jQuery(elem).prepend(newChild);

Exercise

Circular references

var elem = document.createElement('div');
// JavaScript points to DOM
var leaker = {
	elem: elem
};
// DOM points to JavaScript
elem.expando = leaker;

jQuery.data

var elem = document.createElement('div');
var leaker = {
	elem: elem
};
jQuery(elem).data('expando', leaker);

Exercise

Performance

Performance

var list = document.getElementById('perf-list1');
var newItem;
for (var i = 0; i < 5; i++) {
	newItem = document.createElement('li');
	newItem.innerHTML = 'new item';
	list.appendChild(newItem);
}

Performance

var list = document.getElementById('perf-list2');
var fragment = document.createDocumentFragment();
var newItem;
for (var i = 0; i < 5; i++) {
	newItem = document.createElement('li');
	newItem.innerHTML = 'new item';
	fragment.appendChild(newItem);
}
list.appendChild(fragment);

.innerHTML

.innerHTML

<ul id="list">
	<li id="clickable">click me</li>
</ul>

window.onload = function() {
	document.getElementById('clickable')
		.addEventListener('click', function() {
			alert('clicked!');
		}, false);
};

document.getElementById('list')
	.innerHTML += '<li>new item</li>';

The window object

Timeouts and intervals

setTimeout(function() {
	alert('I was delayed!');
}, 2000);

window.screen

window.location

window.location

Finding elements

Overcoming browser differences

function bind(elem, type, handler) {
	if (/msie/i.test(navigator.userAgent)) {
		elem.attachEvent('on' + type, handler);
	} else {
		elem.addEventListener(type, handler, false);
	}
}

Overcoming browser differences

function bind(elem, type, handler) {
	if (elem.attachEvent) {
		elem.attachEvent('on' + type, handler);
	} else {
		elem.addEventListener(type, handler, false);
	}
}

Exercise

References