3. JavaScript can be strange
• Syntactically similar to C++ and Java
“Java is to JavaScript as car is to carpet”
• Prototypal inheritance
• Classless. Objects inherit from objects.
• Loosely typed
• Type coercion. “Truthy” / “falsy” values.
• Objects are mutable
5. NodeLists
Get all the anchors in a page:
var anchors1 = document.getElementsByTagName('a');
[<a href="#">Item 1</a>,
<a href="#">Item 2</a>]
var anchors2 = document.querySelectorAll('a');
[<a href="#">Item 1</a>,
<a href="#">Item 2</a>]
6. NodeLists
User interaction causes more anchors to be
added to the DOM.
More content
including
anchors returned Pagination request
to server
7. NodeLists
One of our NodeLists is automatically
updated:
console.log(anchors1);
[<a href="#">Item 1</a>,
<a href="#">Item 2</a>,
<a href="#">Item 3</a>,
<a href="#">Item 4</a>]
console.log(anchors2);
[<a href="#">Item 1</a>,
<a href="#">Item 2</a>]
10. Scope and Closures
Variables are scoped to functions
var foo = "bar"; //global
function widget() {
var foo = "123"; //scoped to widget
}
11. Scope and Closures
Variables are scoped to functions
var message = 'Hello? Is anybody there?';
function helloWorld() {
var message = 'Hello, world!';
return message;
} // returns "Hello, world!"
12. Scope and Closures
Functions don't need to be named.
A common scoping technique is to use the
Immediately-Invoked Function Expression
(aka IIFE)
13. Scope and Closures
Immediately-Invoked Function Expression:
(function () {
var message = 'Hello, world!',
conferenceName = 'Dr. Dobbs India',
attendees = 'Awesome';
}());
15. Scope and Closures
Functions also create closures.
Closure = Anything declared within a function
is aware of anything else declared within that
function.
16. Scope and Closures
Functions also create closures.
var public = 'Everybody sees this.';
function family() {
var father, mother;
function kids() {
var child1, child2;
}
}
17. Scope and Closures
Building a game leveraging closures:
var game = (function () {
var secret = 5;
return function (num) {
var total = secret * num;
console.log('You say ' + num + ', I say ' +
total + '. What is my secret?');
};
}());
18. Scope and Closures
Building a game leveraging closures:
> game(5)
You say 5, I say 25. What is my secret?
> game(10)
You say 10, I say 50. What is my secret?
> secret
ReferenceError: secret is not defined
19. Scope and Closures
Block scope with let*
if (x) {
let myVar;
let yourVar = 123;
}
* Not yet available everywhere.
20. Scope and Closures
Block scope with let*
var myVar = 5;
let(myVar = 6) {
alert(myVar); // 6
}
alert(myVar); // 5
* Not yet available everywhere.
26. Memoization
var square = (function () {
var memo = [];
return function (num) {
var sqr = memo[num];
if (typeof sqr === 'undefined') {
console.log('Calculating...');
memo[num] = sqr = num * num;
}
return sqr;
}
}());
27. Memoization
var fetchData = (function () {
var data = null, timestamp = new Date().getTime();
return function (url, callback) {
if (timestamp - new Date().getTime() > 60000) {
$.ajax(url, {success: function (d) {
timestamp = new Date().getTime();
data = d;
callback(data);
});
} else {
callback(data);
}
}
}());
37. Function overloading
function calculateAverage(values) {
var total = 0;
if (!Array.isArray(values)) {
values = Array.prototype.slice.call(arguments);
}
values.forEach(function (val) {
total += val;
});
return total / values.length;
}
41. Async Code Execution
What does this code do?
// Load appointments for April
$.ajax('/calendar/2014/04/');
// Show the calendar
showCalendar();
Shows an empty calendar.
42. Async Code Execution
Ajax requests are asynchronous.
The JavaScript engine doesn’t wait.
// Load appointments for April
$.ajax('/calendar/2014/04/');
// Show the calendar
showCalendar();
43. Async Code Execution
Event-driven programming where callback
functions are assigned as event handlers.
When X happens, do Y. Where X is the event
and Y is the code to execute.
44. Async Code Execution
Assigning an Ajax event handler:
// Load appointments for April
$.ajax('/calendar/2014/04/', {
complete: showCalendar
});
45. Async Code Execution
Event handler assignment:
document.onclick = function (e) {
e = e || event;
console.log('Mouse coords: ', e.pageX, ' / ', e.pageY);
}
46. Async Code Execution
Event handler assignment:
document.addEventListener('click', function (e) {
e = e || event;
console.log('Mouse coords: ', e.pageX, ' / ', e.pageY);
});
document.addEventListener('click', function (e) {
e = e || event;
var target = e.target || e.srcElement;
console.log('Click target: ', target);
});
47. Async Code Execution
Event handler assignment:
var xhr = new XMLHttpRequest();
xhr.onload = function () {
console.log(this.responseText);
}
xhr.open('get', ’/weather_data');
xhr.send();
48. Async Code Execution
Event handler context:
document.onclick = function (e) {
// `this` refers to document object
e = e || event;
console.log('Mouse coords: ', e.pageX, ' / ', e.pageY);
}
49. Async Code Execution
Event handler context:
xhr.onload = function () {
// `this` refers to xhr object
console.log(this.responseText);
}
64. Prototypal Inheritance
“All objects in JavaScript are descended from
Object”
Object.prototype.hello = 'world';
var myObject = new Object();
Object
.hello
myObject
.hello
66. Prototypal Inheritance
They have a prototype property allowing
inheritance.
function Person() {};
Person.prototype.name = "Bob";
67. Prototypal Inheritance
You can create an instance of one using the
new keyword:
var person1 = new Person();
console.log(person1.name); // Bob
68. Prototypal Inheritance
Live link with its parent:
function Animal() {}
var dog = new Animal();
Animal.prototype.speak = function (msg) {
console.log(msg)
};
69. Prototypal Inheritance
Live link with its parent:
function Animal() {}
var dog = new Animal();
Animal.prototype.speak = function (msg) {
console.log(msg)
};
dog.speak('woof');
72. Optimization
Rather than assigning individual handlers:
var a = document.getElementById('save');
a.onclick = function () {
// save code
};
73. Optimization
Assign one for all of the same type:
document.onclick = function (e) {
e = e || event;
var target = e.target || e.srcElement;
if (target.id === 'save') {
// save code
}
};