SlideShare a Scribd company logo
1 of 147
Download to read offline
Diving Deep into
JavaScript Functions
By: Colin DeCarlo
colindecarlo@colindecarlo
About Me
colindecarlo@colindecarlo
About Me
colindecarlo@colindecarlo
Colin DeCarlo
Software Developer
PHP & JavaScript
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Why?
colindecarlo@colindecarlo
Other people need to know this
colindecarlo@colindecarlo
–Johnny Appleseed
“Type a quote here.”
colindecarlo@colindecarlo
–Johnny Appleseed
“Type a quote here.”
colindecarlo@colindecarlo
–Johnny Appleseed
“Type a quote here.”
colindecarlo@colindecarlo
Warning
This talk will be technical
colindecarlo@colindecarlo
Agenda
Agenda
(function printAgenda() {
var topics = [
'What is a Function?',
'How do I create these "functions"?',
'What happens when I invoke a Function?',
'How do I wield this power?'
];
return topics.join("n");
})();
// => 'What is a Function?',
// => 'How do I create these "functions"?,
// => 'What happens when I invoke a Function?',
// => 'How do I wield this power?"
What is a JavaScript Function?
colindecarlo@colindecarlo
Functions are Objects
With properties, methods and a {{Prototype}}
Functions are Objects
With properties, methods and a {{Prototype}}
function add(x, y) {
return x + y;
}
Functions are Objects
With properties, methods and a {{Prototype}}
function add(x, y) {
return x + y;
}
Own Properties Inherited Methods
name: add
length: 2
Function.prototype
call
apply
bind
Object.prototype
toString
How do I create these “functions”?
colindecarlo@colindecarlo
Named Function
function named_function() {
return "I'm a named function!"
}
Function Expression
var function_expression = function () {
return "I'm a function expression!";
}
Immediately Invoked Function Expression
(function () {
var button = document.getElementById(
'submit_button'
);
button.addEventListener('click',
function (e) {
this.classList.add('disabled');
}
);
})();
colindecarlo@colindecarlo
colindecarlo@colindecarlo
What happens when I invoke a
function?
colindecarlo@colindecarlo
add(2, 3);
add(2, 3);
Execution Context
add(2, 3);
Execution Context
scope chain
add(2, 3);
Execution Context
scope chain
Activation
Object
add(2, 3);
Execution Context
scope chain
Activation
Object
add(2, 3);
Execution Context
scope chain
Activation
Object
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Scopes
Scopes
var globalVar = 'found in global scope';
function global_function() {
var localVar = 'found in global_function';
function inner_function() {
var innerVar = 'found in inner_function';
console.log(globalVar, localVar, innerVar);
console.log(notFoundAnywhere);
}
inner_function();
}
global_function();
global scope
globalVar: ‘found in global scope’
global_function: [Function]
Scopes
var globalVar = 'found in global scope';
function global_function() {
var localVar = 'found in global_function';
function inner_function() {
var innerVar = 'found in inner_function';
console.log(globalVar, localVar, innerVar);
console.log(notFoundAnywhere);
}
inner_function();
}
global_function();
global scope
globalVar: ‘found in global scope’
global_function: [Function]
global_function scope
Scopes
var globalVar = 'found in global scope';
function global_function() {
var localVar = 'found in global_function';
function inner_function() {
var innerVar = 'found in inner_function';
console.log(globalVar, localVar, innerVar);
console.log(notFoundAnywhere);
}
inner_function();
}
global_function();
global scope
globalVar: ‘found in global scope’
global_function: [Function]
localVar: ‘found in global_function’
inner_function: [Function]
global_function scope
Scopes
var globalVar = 'found in global scope';
function global_function() {
var localVar = 'found in global_function';
function inner_function() {
var innerVar = 'found in inner_function';
console.log(globalVar, localVar, innerVar);
console.log(notFoundAnywhere);
}
inner_function();
}
global_function();
global scope
globalVar: ‘found in global scope’
global_function: [Function]
localVar: ‘found in global_function’
inner_function: [Function]
global_function scope
inner_functon scope
Scopes
var globalVar = 'found in global scope';
function global_function() {
var localVar = 'found in global_function';
function inner_function() {
var innerVar = 'found in inner_function';
console.log(globalVar, localVar, innerVar);
console.log(notFoundAnywhere);
}
inner_function();
}
global_function();
global scope
globalVar: ‘found in global scope’
global_function: [Function]
localVar: ‘found in global_function’
inner_function: [Function]
innerVar: ‘found in inner_function’
global_function scope
inner_functon scope
Scopes
var globalVar = 'found in global scope';
function global_function() {
var localVar = 'found in global_function';
function inner_function() {
var innerVar = 'found in inner_function';
console.log(globalVar, localVar, innerVar);
console.log(notFoundAnywhere);
}
inner_function();
}
global_function();
// => found in global scope, found in global_function, found in inner_function
// => undefined
global scope
globalVar: ‘found in global scope’
global_function: [Function]
localVar: ‘found in global_function’
inner_function: [Function]
innerVar: ‘found in inner_function’
global_function scope
inner_functon scope
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Activation Object
colindecarlo@colindecarlo
this
contains a reference to some object
add(2, 3); this: {{ object }}
var that = this;
colindecarlo@colindecarlo
A function which is simply executed
var debug = true;
function something_complicated() {
if (this.debug) {
console.log('Starting something_complicated');
}
// ...
return complex_result;
}
something_complicated();
A function which is simply executed
var debug = true;
function something_complicated() {
if (this.debug) {
console.log('Starting something_complicated');
}
// ...
return complex_result;
}
something_complicated();
this === window;
// => true
Functions as object properties
var calculator = {
debug: true,
something_complicated: function () {
if (this.debug) {
console.log('Starting something_complicated');
}
// ...
return complex_result;
}
};
calculator.something_complicated();
Functions as object properties
this === calculator;
// => true
var calculator = {
debug: true,
something_complicated: function () {
if (this.debug) {
console.log('Starting something_complicated');
}
// ...
return complex_result;
}
};
calculator.something_complicated();
As element attributes
<button id="calculate" onmouseover="this.style['border-color'] = 'blue';">
Calculate
</button>
As element attributes
this === calculate;
// => true
<button id="calculate" onmouseover="this.style['border-color'] = 'blue';">
Calculate
</button>
Functions as event handlers
<script>
var calculate = document.getElementById('calculate');
calculate.addEventListener('click', function (e) {
this.innerHTML = 'Calculating...';
});
</script>
Functions as event handlers
this === calculate;
// => true
<script>
var calculate = document.getElementById('calculate');
calculate.addEventListener('click', function (e) {
this.innerHTML = 'Calculating...';
});
</script>
In a constructor function
function Circle(radius) {
this.radius = radius;
}
var myCircle = new Circle(42);
In a constructor function
this instanceof Circle;
// => true
function Circle(radius) {
this.radius = radius;
}
var myCircle = new Circle(42);
colindecarlo@colindecarlo
colindecarlo@colindecarlo
arguments
“Array like” object with numerical properties
this: window
add(2, 3);
arguments
“Array like” object with numerical properties
this: window
add(2, 3);
arguments: {
0: 2, 1: 3
}
Named Formal Parameters
this: window
add(2, 3); arguments: {
0: 2, 1: 3
}
Named Formal Parameters
this: window
add(2, 3); arguments: {
0: 2, 1: 3
}
x: 2
y: 3
Declaration and Hoisting
function concat() {
return " ".join(to_array(arguments));
function to_array(args) {
var words = [];
for (var i = 0; i < args.length; i++) {
words.push(args[i]);
}
return words;
}
}
Declaration and Hoisting
functions are declared
function concat() {
return " ".join(to_array(arguments));
function to_array(args) {
var words = [];
for (var i = 0; i < args.length; i++) {
words.push(args[i]);
}
return words;
}
}
Declaration and Hoisting
functions are declared
variables are declared
function concat() {
return " ".join(to_array(arguments));
function to_array(args) {
var words = [];
for (var i = 0; i < args.length; i++) {
words.push(args[i]);
}
return words;
}
}
Declaration and Hoisting
function concat() {
return " ".join(to_array(arguments));
function to_array(args) {
var words = [];
for (var i = 0; i < args.length; i++) {
words.push(args[i]);
}
return words;
}
}
function concat() {
function to_array(args) {
var words = [],
i;
for (i = 0; i < args.length; i++) {
words.push(args[i]);
}
return words;
}
return " ".join(to_array(arguments));
}
Hoisting: One Simple Rule
colindecarlo@colindecarlo
Hoisting: One Simple Rule
colindecarlo@colindecarlo
Don’t. Declare all variables and functions at the top.
colindecarlo@colindecarlo
colindecarlo@colindecarlo
What happens when I invoke a
function?
colindecarlo@colindecarlo
What happens when I invoke a
function?
colindecarlo@colindecarlo
What happens when I invoke a
function?
colindecarlo@colindecarlo
• The Execution Context is created and placed on top of the execution stack
What happens when I invoke a
function?
colindecarlo@colindecarlo
• The Execution Context is created and placed on top of the execution stack
• this and arguments are declared and assigned
What happens when I invoke a
function?
colindecarlo@colindecarlo
• The Execution Context is created and placed on top of the execution stack
• this and arguments are declared and assigned
• Named formal parameters are declared and assigned
What happens when I invoke a
function?
colindecarlo@colindecarlo
• The Execution Context is created and placed on top of the execution stack
• this and arguments are declared and assigned
• Named formal parameters are declared and assigned
• Named functions are declared
What happens when I invoke a
function?
colindecarlo@colindecarlo
• The Execution Context is created and placed on top of the execution stack
• this and arguments are declared and assigned
• Named formal parameters are declared and assigned
• Named functions are declared
• Local variables are declared
How may I wield this power?
colindecarlo@colindecarlo
Variadic Functions
var colors = enumer('RED', 'GREEN', ‘BLUE’),
selectedColor = ‘RED’;
colors.contains(selectedColor);
// => true
selectedColor = ‘YELLOW’;
colors.contains(selectedColor);
// => false
Variadic Functions
var colors = enumer('RED', 'GREEN', ‘BLUE’),
selectedColor = ‘RED’;
colors.contains(selectedColor);
// => true
selectedColor = ‘YELLOW’;
colors.contains(selectedColor);
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Variadic Functions
var colors = enumer('RED', 'GREEN', ‘BLUE’),
selectedColor = ‘RED’;
colors.contains(selectedColor);
// => true
selectedColor = ‘YELLOW’;
colors.contains(selectedColor);
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Variadic Functions
var colors = enumer('RED', 'GREEN', ‘BLUE’),
selectedColor = ‘RED’;
colors.contains(selectedColor);
// => true
selectedColor = ‘YELLOW’;
colors.contains(selectedColor);
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Variadic Functions
var colors = enumer('RED', 'GREEN', ‘BLUE’),
selectedColor = ‘RED’;
colors.contains(selectedColor);
// => true
selectedColor = ‘YELLOW’;
colors.contains(selectedColor);
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Variadic Functions
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Modifying Context
Taking control of this
call(thisArg, arg1, …, argN)
use to set the value of this when you know the number
of arguments and what they are
Modifying Context
Taking control of this
apply(thisArg, argsArray)
use to set the value of this when you don’t know the number
of arguments
Modifying Context
Taking control of this
bind(thisArg, arg1, …, argN)
use to set the value of this but without executing the function
colindecarlo@colindecarlo
colindecarlo@colindecarlo
function memoize(func, context) {
var results = {},
wrapper = function () {
var args = Array.prototype.slice.call(arguments, 0),
key = ':'.join(args);
if (!results.hasOwnProperty(key)) {
results[key] = func.apply(context, args);
}
return results[key];
};
return wrapper;
}
function memoize(func, context) {
var results = {},
wrapper = function () {
var args = Array.prototype.slice.call(arguments, 0),
key = ':'.join(args);
if (!results.hasOwnProperty(key)) {
results[key] = func.apply(context, args);
}
return results[key];
};
return wrapper;
}
Partial Application with bind
the process of taking a function which accepts N arguments and turning it

into a function which accepts N - x arguments
Partial Application with bind
function add(x, y) {
return x + y;
}
var plus42 = add.bind(undefined, 42);
plus42(42);
the process of taking a function which accepts N arguments and turning it

into a function which accepts N - x arguments
Partial Application with bind
function add(x, y) {
return x + y;
}
var plus42 = add.bind(undefined, 42);
plus42(42);
// => 84
the process of taking a function which accepts N arguments and turning it

into a function which accepts N - x arguments
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Closures
A function which “closes over” a variable from an outer scope
Closures
A function which holds a reference to another function’s Activation Object
thus allowing that function to access variables and functions defined
within it
Closures
function plusX(x) {
return function(n) {
return n + x;
};
}
A function which holds a reference to another function’s Activation Object
thus allowing that function to access variables and functions defined
within it
Closures
function plusX(x) {
return function(n) {
return n + x;
};
}
var plus42 = plusX(42);
plus42(1);
// => 43
A function which holds a reference to another function’s Activation Object
thus allowing that function to access variables and functions defined
within it
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Trick Question
colindecarlo@colindecarlo
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push(function () {
console.log(i);
});
}
for (var j = 0; j < 5; j++) {
funcs[j]();
}
// => 5
// => 5
// => 5
// => 5
// => 5
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push(function () {
console.log(i);
});
}
for (var j = 0; j < 5; j++) {
funcs[j]();
}
// => 5
// => 5
// => 5
// => 5
// => 5
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push(function () {
console.log(i);
});
}
for (var j = 0; j < 5; j++) {
funcs[j]();
}
// => 0
// => 1
// => 2
// => 3
// => 4
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push((function (i) {
return function () {
console.log(i);
};
})(i));
}
for (var j = 0; j < 5; j++) {
funcs[j]();
}
// => 0
// => 1
// => 2
// => 3
// => 4
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push((function (i) {
return function () {
console.log(i);
};
})(i));
}
for (var j = 0; j < 5; j++) {
funcs[j]();
}
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Encapsulation: A Better enumer
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
colors.YELLOW = 'YOLO';
colors.contains('YELLOW');
// => true
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
colors.YELLOW = 'YOLO';
colors.contains('YELLOW');
// => true
delete colors.RED;
colors.contains('RED');
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
colors.YELLOW = 'YOLO';
colors.contains('YELLOW');
// => true
colors.contains('contains');
// => true
delete colors.RED;
colors.contains('RED');
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
function enumer() {
function contains (value) {
return this.hasOwnProperty(value);
}
var i, numValues = arguments.length,
values = {};
for (i = 0; i < numValues; i++) {
values[arguments[i]] = arguments[i];
}
values.contains = contains;
return values;
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
function enumer() {
var slice = Array.prototype.slice,
values = slice.call(arguments, 0);
return {
contains: function (value) {
return values.indexOf(value) >= 0;
}
};
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
colors.YELLOW = 'YOLO';
colors.contains('YELLOW');
// => false
delete colors.RED;
colors.contains('RED');
// => true
function enumer() {
var slice = Array.prototype.slice,
values = slice.call(arguments, 0);
return {
contains: function (value) {
return values.indexOf(value) >= 0;
}
};
}
Encapsulation: A Better enumer
var colors = enumer('RED', 'GREEN', 'BLUE');
colors.contains('RED');
// => true
colors.contains('YELLOW');
// => false
colors.YELLOW = 'YOLO';
colors.contains('YELLOW');
// => false
delete colors.RED;
colors.contains('RED');
// => true
colors.contains('contains');
// => false
function enumer() {
var slice = Array.prototype.slice,
values = slice.call(arguments, 0);
return {
contains: function (value) {
return values.indexOf(value) >= 0;
}
};
}
colindecarlo@colindecarlo
colindecarlo@colindecarlo
colindecarlo@colindecarlo
Questions?
https://joind.in/15748
colindecarlo@colindecarlo
Questions?
https://joind.in/15748
var someObject = Class.extend({
init: function () {
$('.some-selector').on('click', this.onClick.bind(this));
},
onClick: function (e) {
var result = this.helperFunction();
return this.format(result);
}
};
Modifying Context
Taking control of this
Modifying Context
Taking control of this
`call`
`apply`
`bind`
Modifying Context
Taking control of this
`call`
`apply`
`bind`
Modifying Context
Taking control of this
`call`
`apply`
`bind`
use to set the value of `this` when you know the number
of arguments and what they are
Modifying Context
Taking control of this
`call`
`apply`
`bind`
use to set the value of `this` when you know the number
of arguments and what they are
use to set the value of `this` when you don’t know the
number of arguments
Modifying Context
Taking control of this
`call`
`apply`
`bind`
use to set the value of `this` when you know the number
of arguments and what they are
use to set the value of `this` when you don’t know the
number of arguments
use to set the value of `this` but without executing the
function
Modifying Context
Taking control of this
Modifying Context
Taking control of this
`call`
`apply`
`bind`
Modifying Context
Taking control of this
`call`
`apply`
`bind`
Modifying Context
Taking control of this
`call`
`apply`
`bind`
use to set the value of `this` when you know the number
of arguments and what they are
Modifying Context
Taking control of this
`call`
`apply`
`bind`
use to set the value of `this` when you know the number
of arguments and what they are
use to set the value of `this` when you don’t know the
number of arguments
Modifying Context
Taking control of this
`call`
`apply`
`bind`
use to set the value of `this` when you know the number
of arguments and what they are
use to set the value of `this` when you don’t know the
number of arguments
use to set the value of `this` but without executing the
function
Trick Question
colindecarlo@colindecarlo
function getEventListener(sniffer) {
function on(event, callback) {
window.addEventListener(event, callback);
}
if (sniffer.isIE()) {
function on(event, callback) {
window.attachEvent(event, callback);
}
}
return on;
}
var browserSniffer = {
isIE: function () {
return false;
}
};
getEventListener(browserSniffer).toString();
function getEventListener(sniffer) {
function on(event, callback) {
window.addEventListener(event, callback);
}
if (sniffer.isIE()) {
function on(event, callback) {
window.attachEvent(event, callback);
}
}
return on;
}
var browserSniffer = {
isIE: function () {
return false;
}
};
getEventListener(browserSniffer).toString();
function getEventListener(sniffer) {
function on(event, callback) {
window.addEventListener(event, callback);
}
if (sniffer.isIE()) {
function on(event, callback) {
window.attachEvent(event, callback);
}
}
return on;
}
var browserSniffer = {
isIE: function () {
return false;
}
};
getEventListener(browserSniffer).toString();
function getEventListener(sniffer) {
function on(event, callback) {
window.addEventListener(event, callback);
}
if (sniffer.isIE()) {
function on(event, callback) {
window.attachEvent(event, callback);
}
}
return on;
}
var browserSniffer = {
isIE: function () {
return false;
}
};
getEventListener(browserSniffer).toString();
function getEventListener(sniffer) {
function on(event, callback) {
window.addEventListener(event, callback);
}
if (sniffer.isIE()) {
function on(event, callback) {
window.attachEvent(event, callback);
}
}
return on;
}
var browserSniffer = {
isIE: function () {
return false;
}
};
getEventListener(browserSniffer).toString();
function getEventListener(sniffer) {
function on(event, callback) {
window.addEventListener(event, callback);
}
if (sniffer.isIE()) {
function on(event, callback) {
window.attachEvent(event, callback);
}
}
return on;
}
var browserSniffer = {
isIE: function () {
return false;
}
};
getEventListener(browserSniffer).toString();
function on(event, callback) {
window.attachEvent(event, callback);
}
Encapsulation the JavaScript Way
Encapsulation the JavaScript Way
function Vault(passcode) {
var locked = true,
data = {};
function checkPasscode(attemptedPasscode) {
return attemptedPasscode == passcode;
}
function grantAccess() {
locked = false;
return true;
}
this.isLocked = function () {
return locked;
};
this.lock = function () {
locked = true;
};
// ...
Encapsulation the JavaScript Way
function Vault(passcode) {
var locked = true,
data = {};
function checkPasscode(attemptedPasscode) {
return attemptedPasscode == passcode;
}
function grantAccess() {
locked = false;
return true;
}
this.isLocked = function () {
return locked;
};
this.lock = function () {
locked = true;
};
// ...
// ...
this.unlock = function (attemptedPasscode) {
checkPasscode(attemptedPasscode) && grantAccess();
};
this.store = function (key, value) {
if (this.isLocked()) {
throw new Error('The vault is locked');
}
data[key] = value;
};
this.retrieve = function (key) {
if (this.isLocked) {
throw new Error('The vault is locked');
}
return data[key];
};
}
$ node encapsulation.js
var v = new Vault('sekret');
v.isLocked();
true
v.unlock('sekret')
v.store('js_functions', 'Awesome')
v.retrieve(‘js_functions')
Awesome
v.lock()
v.isLocked()
true
v.retrieve('js_functions')
/Users/colin/Documents/talks/js_functions/encapsulation.js:40
throw new Error('The vault is locked');
^
Error: The vault is locked
at Vault.retrieve (/Users/colin/Documents/talks/js_functions/encapsulation.js:40:19)
at Object.<anonymous> (/Users/colin/Documents/talks/js_functions/encapsulation.js:68:3)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3

More Related Content

What's hot

Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
Adieu
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 

What's hot (20)

DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharp
 
JavaScript introduction 1 ( Variables And Values )
JavaScript introduction 1 ( Variables And Values )JavaScript introduction 1 ( Variables And Values )
JavaScript introduction 1 ( Variables And Values )
 
Javascript
JavascriptJavascript
Javascript
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design Patterns
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
 
Functional programming in Javascript
Functional programming in JavascriptFunctional programming in Javascript
Functional programming in Javascript
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 

Viewers also liked

Week 5 java script functions
Week 5  java script functionsWeek 5  java script functions
Week 5 java script functions
brianjihoonlee
 

Viewers also liked (17)

Week 5 java script functions
Week 5  java script functionsWeek 5  java script functions
Week 5 java script functions
 
Functions in javascript
Functions in javascriptFunctions in javascript
Functions in javascript
 
Java server faces
Java server facesJava server faces
Java server faces
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
DHTML
DHTMLDHTML
DHTML
 
Java script
Java scriptJava script
Java script
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
9. java server faces
9. java server faces9. java server faces
9. java server faces
 
Web servers
Web serversWeb servers
Web servers
 
Ruby on Rails for beginners
Ruby on Rails for beginnersRuby on Rails for beginners
Ruby on Rails for beginners
 
Data warehouse,data mining & Big Data
Data warehouse,data mining & Big DataData warehouse,data mining & Big Data
Data warehouse,data mining & Big Data
 
Java Server Faces (JSF) - Basics
Java Server Faces (JSF) - BasicsJava Server Faces (JSF) - Basics
Java Server Faces (JSF) - Basics
 
Ajax Ppt
Ajax PptAjax Ppt
Ajax Ppt
 
Javascript
JavascriptJavascript
Javascript
 
Java Script (shqip)
Java Script (shqip) Java Script (shqip)
Java Script (shqip)
 
Ajax ppt - 32 slides
Ajax ppt - 32 slidesAjax ppt - 32 slides
Ajax ppt - 32 slides
 
Web Servers (ppt)
Web Servers (ppt)Web Servers (ppt)
Web Servers (ppt)
 

Similar to JavaScript Functions

Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web Module
Morgan Cheng
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
rajivmordani
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
wpnepal
 
Converting your JS library to a jQuery plugin
Converting your JS library to a jQuery pluginConverting your JS library to a jQuery plugin
Converting your JS library to a jQuery plugin
thehoagie
 

Similar to JavaScript Functions (20)

Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web Module
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)
 
JavaScript Literacy
JavaScript LiteracyJavaScript Literacy
JavaScript Literacy
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
AngularJS Testing Strategies
AngularJS Testing StrategiesAngularJS Testing Strategies
AngularJS Testing Strategies
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscore
 
Testing AngularJS
Testing AngularJSTesting AngularJS
Testing AngularJS
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJS
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
 
04 Advanced Javascript
04 Advanced Javascript04 Advanced Javascript
04 Advanced Javascript
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes[AngularJS] From Angular to Mobile in 30 minutes
[AngularJS] From Angular to Mobile in 30 minutes
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Hooks WCSD12
Hooks WCSD12Hooks WCSD12
Hooks WCSD12
 
Converting your JS library to a jQuery plugin
Converting your JS library to a jQuery pluginConverting your JS library to a jQuery plugin
Converting your JS library to a jQuery plugin
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
 

Recently uploaded

一比一原版帝国理工学院毕业证如何办理
一比一原版帝国理工学院毕业证如何办理一比一原版帝国理工学院毕业证如何办理
一比一原版帝国理工学院毕业证如何办理
F
 
一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样
一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样
一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样
ayvbos
 
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu DhabiAbu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Monica Sydney
 
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
gajnagarg
 
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
ydyuyu
 
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girlsRussian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Monica Sydney
 
一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理
一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理
一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理
AS
 

Recently uploaded (20)

PIC Microcontroller Structure & Assembly Language.ppsx
PIC Microcontroller Structure & Assembly Language.ppsxPIC Microcontroller Structure & Assembly Language.ppsx
PIC Microcontroller Structure & Assembly Language.ppsx
 
Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...
Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...
Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...
 
Ballia Escorts Service Girl ^ 9332606886, WhatsApp Anytime Ballia
Ballia Escorts Service Girl ^ 9332606886, WhatsApp Anytime BalliaBallia Escorts Service Girl ^ 9332606886, WhatsApp Anytime Ballia
Ballia Escorts Service Girl ^ 9332606886, WhatsApp Anytime Ballia
 
Sensual Call Girls in Tarn Taran Sahib { 9332606886 } VVIP NISHA Call Girls N...
Sensual Call Girls in Tarn Taran Sahib { 9332606886 } VVIP NISHA Call Girls N...Sensual Call Girls in Tarn Taran Sahib { 9332606886 } VVIP NISHA Call Girls N...
Sensual Call Girls in Tarn Taran Sahib { 9332606886 } VVIP NISHA Call Girls N...
 
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrStory Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
 
一比一原版帝国理工学院毕业证如何办理
一比一原版帝国理工学院毕业证如何办理一比一原版帝国理工学院毕业证如何办理
一比一原版帝国理工学院毕业证如何办理
 
一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样
一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样
一比一原版(Curtin毕业证书)科廷大学毕业证原件一模一样
 
APNIC Updates presented by Paul Wilson at ARIN 53
APNIC Updates presented by Paul Wilson at ARIN 53APNIC Updates presented by Paul Wilson at ARIN 53
APNIC Updates presented by Paul Wilson at ARIN 53
 
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
 
Down bad crying at the gym t shirtsDown bad crying at the gym t shirts
Down bad crying at the gym t shirtsDown bad crying at the gym t shirtsDown bad crying at the gym t shirtsDown bad crying at the gym t shirts
Down bad crying at the gym t shirtsDown bad crying at the gym t shirts
 
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
 
South Bopal [ (Call Girls) in Ahmedabad ₹7.5k Pick Up & Drop With Cash Paymen...
South Bopal [ (Call Girls) in Ahmedabad ₹7.5k Pick Up & Drop With Cash Paymen...South Bopal [ (Call Girls) in Ahmedabad ₹7.5k Pick Up & Drop With Cash Paymen...
South Bopal [ (Call Girls) in Ahmedabad ₹7.5k Pick Up & Drop With Cash Paymen...
 
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu DhabiAbu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
 
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
 
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
 
Real Men Wear Diapers T Shirts sweatshirt
Real Men Wear Diapers T Shirts sweatshirtReal Men Wear Diapers T Shirts sweatshirt
Real Men Wear Diapers T Shirts sweatshirt
 
💚 Call Girls Bahraich 9332606886 High Profile Call Girls You Can Get The S...
💚 Call Girls Bahraich   9332606886  High Profile Call Girls You Can Get The S...💚 Call Girls Bahraich   9332606886  High Profile Call Girls You Can Get The S...
💚 Call Girls Bahraich 9332606886 High Profile Call Girls You Can Get The S...
 
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girlsRussian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
 
一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理
一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理
一比一原版(Dundee毕业证书)英国爱丁堡龙比亚大学毕业证如何办理
 
Trump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts SweatshirtTrump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts Sweatshirt
 

JavaScript Functions

  • 1. Diving Deep into JavaScript Functions By: Colin DeCarlo colindecarlo@colindecarlo
  • 7. Other people need to know this colindecarlo@colindecarlo
  • 8. –Johnny Appleseed “Type a quote here.” colindecarlo@colindecarlo
  • 9. –Johnny Appleseed “Type a quote here.” colindecarlo@colindecarlo
  • 10. –Johnny Appleseed “Type a quote here.” colindecarlo@colindecarlo
  • 11. Warning This talk will be technical colindecarlo@colindecarlo
  • 13. Agenda (function printAgenda() { var topics = [ 'What is a Function?', 'How do I create these "functions"?', 'What happens when I invoke a Function?', 'How do I wield this power?' ]; return topics.join("n"); })(); // => 'What is a Function?', // => 'How do I create these "functions"?, // => 'What happens when I invoke a Function?', // => 'How do I wield this power?"
  • 14. What is a JavaScript Function? colindecarlo@colindecarlo
  • 15. Functions are Objects With properties, methods and a {{Prototype}}
  • 16. Functions are Objects With properties, methods and a {{Prototype}} function add(x, y) { return x + y; }
  • 17. Functions are Objects With properties, methods and a {{Prototype}} function add(x, y) { return x + y; } Own Properties Inherited Methods name: add length: 2 Function.prototype call apply bind Object.prototype toString
  • 18. How do I create these “functions”? colindecarlo@colindecarlo
  • 19. Named Function function named_function() { return "I'm a named function!" }
  • 20. Function Expression var function_expression = function () { return "I'm a function expression!"; }
  • 21. Immediately Invoked Function Expression (function () { var button = document.getElementById( 'submit_button' ); button.addEventListener('click', function (e) { this.classList.add('disabled'); } ); })();
  • 24. What happens when I invoke a function? colindecarlo@colindecarlo
  • 28. add(2, 3); Execution Context scope chain Activation Object
  • 29. add(2, 3); Execution Context scope chain Activation Object
  • 30. add(2, 3); Execution Context scope chain Activation Object
  • 34. Scopes var globalVar = 'found in global scope'; function global_function() { var localVar = 'found in global_function'; function inner_function() { var innerVar = 'found in inner_function'; console.log(globalVar, localVar, innerVar); console.log(notFoundAnywhere); } inner_function(); } global_function(); global scope globalVar: ‘found in global scope’ global_function: [Function]
  • 35. Scopes var globalVar = 'found in global scope'; function global_function() { var localVar = 'found in global_function'; function inner_function() { var innerVar = 'found in inner_function'; console.log(globalVar, localVar, innerVar); console.log(notFoundAnywhere); } inner_function(); } global_function(); global scope globalVar: ‘found in global scope’ global_function: [Function] global_function scope
  • 36. Scopes var globalVar = 'found in global scope'; function global_function() { var localVar = 'found in global_function'; function inner_function() { var innerVar = 'found in inner_function'; console.log(globalVar, localVar, innerVar); console.log(notFoundAnywhere); } inner_function(); } global_function(); global scope globalVar: ‘found in global scope’ global_function: [Function] localVar: ‘found in global_function’ inner_function: [Function] global_function scope
  • 37. Scopes var globalVar = 'found in global scope'; function global_function() { var localVar = 'found in global_function'; function inner_function() { var innerVar = 'found in inner_function'; console.log(globalVar, localVar, innerVar); console.log(notFoundAnywhere); } inner_function(); } global_function(); global scope globalVar: ‘found in global scope’ global_function: [Function] localVar: ‘found in global_function’ inner_function: [Function] global_function scope inner_functon scope
  • 38. Scopes var globalVar = 'found in global scope'; function global_function() { var localVar = 'found in global_function'; function inner_function() { var innerVar = 'found in inner_function'; console.log(globalVar, localVar, innerVar); console.log(notFoundAnywhere); } inner_function(); } global_function(); global scope globalVar: ‘found in global scope’ global_function: [Function] localVar: ‘found in global_function’ inner_function: [Function] innerVar: ‘found in inner_function’ global_function scope inner_functon scope
  • 39. Scopes var globalVar = 'found in global scope'; function global_function() { var localVar = 'found in global_function'; function inner_function() { var innerVar = 'found in inner_function'; console.log(globalVar, localVar, innerVar); console.log(notFoundAnywhere); } inner_function(); } global_function(); // => found in global scope, found in global_function, found in inner_function // => undefined global scope globalVar: ‘found in global scope’ global_function: [Function] localVar: ‘found in global_function’ inner_function: [Function] innerVar: ‘found in inner_function’ global_function scope inner_functon scope
  • 43. this contains a reference to some object add(2, 3); this: {{ object }}
  • 44. var that = this; colindecarlo@colindecarlo
  • 45. A function which is simply executed var debug = true; function something_complicated() { if (this.debug) { console.log('Starting something_complicated'); } // ... return complex_result; } something_complicated();
  • 46. A function which is simply executed var debug = true; function something_complicated() { if (this.debug) { console.log('Starting something_complicated'); } // ... return complex_result; } something_complicated(); this === window; // => true
  • 47. Functions as object properties var calculator = { debug: true, something_complicated: function () { if (this.debug) { console.log('Starting something_complicated'); } // ... return complex_result; } }; calculator.something_complicated();
  • 48. Functions as object properties this === calculator; // => true var calculator = { debug: true, something_complicated: function () { if (this.debug) { console.log('Starting something_complicated'); } // ... return complex_result; } }; calculator.something_complicated();
  • 49. As element attributes <button id="calculate" onmouseover="this.style['border-color'] = 'blue';"> Calculate </button>
  • 50. As element attributes this === calculate; // => true <button id="calculate" onmouseover="this.style['border-color'] = 'blue';"> Calculate </button>
  • 51. Functions as event handlers <script> var calculate = document.getElementById('calculate'); calculate.addEventListener('click', function (e) { this.innerHTML = 'Calculating...'; }); </script>
  • 52. Functions as event handlers this === calculate; // => true <script> var calculate = document.getElementById('calculate'); calculate.addEventListener('click', function (e) { this.innerHTML = 'Calculating...'; }); </script>
  • 53. In a constructor function function Circle(radius) { this.radius = radius; } var myCircle = new Circle(42);
  • 54. In a constructor function this instanceof Circle; // => true function Circle(radius) { this.radius = radius; } var myCircle = new Circle(42);
  • 57. arguments “Array like” object with numerical properties this: window add(2, 3);
  • 58. arguments “Array like” object with numerical properties this: window add(2, 3); arguments: { 0: 2, 1: 3 }
  • 59. Named Formal Parameters this: window add(2, 3); arguments: { 0: 2, 1: 3 }
  • 60. Named Formal Parameters this: window add(2, 3); arguments: { 0: 2, 1: 3 } x: 2 y: 3
  • 61. Declaration and Hoisting function concat() { return " ".join(to_array(arguments)); function to_array(args) { var words = []; for (var i = 0; i < args.length; i++) { words.push(args[i]); } return words; } }
  • 62. Declaration and Hoisting functions are declared function concat() { return " ".join(to_array(arguments)); function to_array(args) { var words = []; for (var i = 0; i < args.length; i++) { words.push(args[i]); } return words; } }
  • 63. Declaration and Hoisting functions are declared variables are declared function concat() { return " ".join(to_array(arguments)); function to_array(args) { var words = []; for (var i = 0; i < args.length; i++) { words.push(args[i]); } return words; } }
  • 64. Declaration and Hoisting function concat() { return " ".join(to_array(arguments)); function to_array(args) { var words = []; for (var i = 0; i < args.length; i++) { words.push(args[i]); } return words; } } function concat() { function to_array(args) { var words = [], i; for (i = 0; i < args.length; i++) { words.push(args[i]); } return words; } return " ".join(to_array(arguments)); }
  • 65. Hoisting: One Simple Rule colindecarlo@colindecarlo
  • 66. Hoisting: One Simple Rule colindecarlo@colindecarlo Don’t. Declare all variables and functions at the top.
  • 69. What happens when I invoke a function? colindecarlo@colindecarlo
  • 70. What happens when I invoke a function? colindecarlo@colindecarlo
  • 71. What happens when I invoke a function? colindecarlo@colindecarlo • The Execution Context is created and placed on top of the execution stack
  • 72. What happens when I invoke a function? colindecarlo@colindecarlo • The Execution Context is created and placed on top of the execution stack • this and arguments are declared and assigned
  • 73. What happens when I invoke a function? colindecarlo@colindecarlo • The Execution Context is created and placed on top of the execution stack • this and arguments are declared and assigned • Named formal parameters are declared and assigned
  • 74. What happens when I invoke a function? colindecarlo@colindecarlo • The Execution Context is created and placed on top of the execution stack • this and arguments are declared and assigned • Named formal parameters are declared and assigned • Named functions are declared
  • 75. What happens when I invoke a function? colindecarlo@colindecarlo • The Execution Context is created and placed on top of the execution stack • this and arguments are declared and assigned • Named formal parameters are declared and assigned • Named functions are declared • Local variables are declared
  • 76. How may I wield this power? colindecarlo@colindecarlo
  • 78. var colors = enumer('RED', 'GREEN', ‘BLUE’), selectedColor = ‘RED’; colors.contains(selectedColor); // => true selectedColor = ‘YELLOW’; colors.contains(selectedColor); // => false Variadic Functions
  • 79. var colors = enumer('RED', 'GREEN', ‘BLUE’), selectedColor = ‘RED’; colors.contains(selectedColor); // => true selectedColor = ‘YELLOW’; colors.contains(selectedColor); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; } Variadic Functions
  • 80. var colors = enumer('RED', 'GREEN', ‘BLUE’), selectedColor = ‘RED’; colors.contains(selectedColor); // => true selectedColor = ‘YELLOW’; colors.contains(selectedColor); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; } Variadic Functions
  • 81. var colors = enumer('RED', 'GREEN', ‘BLUE’), selectedColor = ‘RED’; colors.contains(selectedColor); // => true selectedColor = ‘YELLOW’; colors.contains(selectedColor); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; } Variadic Functions
  • 82. var colors = enumer('RED', 'GREEN', ‘BLUE’), selectedColor = ‘RED’; colors.contains(selectedColor); // => true selectedColor = ‘YELLOW’; colors.contains(selectedColor); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; } Variadic Functions
  • 85. Modifying Context Taking control of this call(thisArg, arg1, …, argN) use to set the value of this when you know the number of arguments and what they are
  • 86. Modifying Context Taking control of this apply(thisArg, argsArray) use to set the value of this when you don’t know the number of arguments
  • 87. Modifying Context Taking control of this bind(thisArg, arg1, …, argN) use to set the value of this but without executing the function
  • 90. function memoize(func, context) { var results = {}, wrapper = function () { var args = Array.prototype.slice.call(arguments, 0), key = ':'.join(args); if (!results.hasOwnProperty(key)) { results[key] = func.apply(context, args); } return results[key]; }; return wrapper; }
  • 91. function memoize(func, context) { var results = {}, wrapper = function () { var args = Array.prototype.slice.call(arguments, 0), key = ':'.join(args); if (!results.hasOwnProperty(key)) { results[key] = func.apply(context, args); } return results[key]; }; return wrapper; }
  • 92. Partial Application with bind the process of taking a function which accepts N arguments and turning it
 into a function which accepts N - x arguments
  • 93. Partial Application with bind function add(x, y) { return x + y; } var plus42 = add.bind(undefined, 42); plus42(42); the process of taking a function which accepts N arguments and turning it
 into a function which accepts N - x arguments
  • 94. Partial Application with bind function add(x, y) { return x + y; } var plus42 = add.bind(undefined, 42); plus42(42); // => 84 the process of taking a function which accepts N arguments and turning it
 into a function which accepts N - x arguments
  • 97. Closures A function which “closes over” a variable from an outer scope
  • 98. Closures A function which holds a reference to another function’s Activation Object thus allowing that function to access variables and functions defined within it
  • 99. Closures function plusX(x) { return function(n) { return n + x; }; } A function which holds a reference to another function’s Activation Object thus allowing that function to access variables and functions defined within it
  • 100. Closures function plusX(x) { return function(n) { return n + x; }; } var plus42 = plusX(42); plus42(1); // => 43 A function which holds a reference to another function’s Activation Object thus allowing that function to access variables and functions defined within it
  • 104. var funcs = []; for (var i = 0; i < 5; i++) { funcs.push(function () { console.log(i); }); } for (var j = 0; j < 5; j++) { funcs[j](); }
  • 105. // => 5 // => 5 // => 5 // => 5 // => 5 var funcs = []; for (var i = 0; i < 5; i++) { funcs.push(function () { console.log(i); }); } for (var j = 0; j < 5; j++) { funcs[j](); }
  • 106. // => 5 // => 5 // => 5 // => 5 // => 5 var funcs = []; for (var i = 0; i < 5; i++) { funcs.push(function () { console.log(i); }); } for (var j = 0; j < 5; j++) { funcs[j](); }
  • 107. // => 0 // => 1 // => 2 // => 3 // => 4 var funcs = []; for (var i = 0; i < 5; i++) { funcs.push((function (i) { return function () { console.log(i); }; })(i)); } for (var j = 0; j < 5; j++) { funcs[j](); }
  • 108. // => 0 // => 1 // => 2 // => 3 // => 4 var funcs = []; for (var i = 0; i < 5; i++) { funcs.push((function (i) { return function () { console.log(i); }; })(i)); } for (var j = 0; j < 5; j++) { funcs[j](); }
  • 112. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; }
  • 113. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false colors.YELLOW = 'YOLO'; colors.contains('YELLOW'); // => true function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; }
  • 114. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false colors.YELLOW = 'YOLO'; colors.contains('YELLOW'); // => true delete colors.RED; colors.contains('RED'); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; }
  • 115. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false colors.YELLOW = 'YOLO'; colors.contains('YELLOW'); // => true colors.contains('contains'); // => true delete colors.RED; colors.contains('RED'); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; }
  • 116. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false function enumer() { function contains (value) { return this.hasOwnProperty(value); } var i, numValues = arguments.length, values = {}; for (i = 0; i < numValues; i++) { values[arguments[i]] = arguments[i]; } values.contains = contains; return values; }
  • 117. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false function enumer() { var slice = Array.prototype.slice, values = slice.call(arguments, 0); return { contains: function (value) { return values.indexOf(value) >= 0; } }; }
  • 118. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false colors.YELLOW = 'YOLO'; colors.contains('YELLOW'); // => false delete colors.RED; colors.contains('RED'); // => true function enumer() { var slice = Array.prototype.slice, values = slice.call(arguments, 0); return { contains: function (value) { return values.indexOf(value) >= 0; } }; }
  • 119. Encapsulation: A Better enumer var colors = enumer('RED', 'GREEN', 'BLUE'); colors.contains('RED'); // => true colors.contains('YELLOW'); // => false colors.YELLOW = 'YOLO'; colors.contains('YELLOW'); // => false delete colors.RED; colors.contains('RED'); // => true colors.contains('contains'); // => false function enumer() { var slice = Array.prototype.slice, values = slice.call(arguments, 0); return { contains: function (value) { return values.indexOf(value) >= 0; } }; }
  • 124. var someObject = Class.extend({ init: function () { $('.some-selector').on('click', this.onClick.bind(this)); }, onClick: function (e) { var result = this.helperFunction(); return this.format(result); } };
  • 126. Modifying Context Taking control of this `call` `apply` `bind`
  • 127. Modifying Context Taking control of this `call` `apply` `bind`
  • 128. Modifying Context Taking control of this `call` `apply` `bind` use to set the value of `this` when you know the number of arguments and what they are
  • 129. Modifying Context Taking control of this `call` `apply` `bind` use to set the value of `this` when you know the number of arguments and what they are use to set the value of `this` when you don’t know the number of arguments
  • 130. Modifying Context Taking control of this `call` `apply` `bind` use to set the value of `this` when you know the number of arguments and what they are use to set the value of `this` when you don’t know the number of arguments use to set the value of `this` but without executing the function
  • 132. Modifying Context Taking control of this `call` `apply` `bind`
  • 133. Modifying Context Taking control of this `call` `apply` `bind`
  • 134. Modifying Context Taking control of this `call` `apply` `bind` use to set the value of `this` when you know the number of arguments and what they are
  • 135. Modifying Context Taking control of this `call` `apply` `bind` use to set the value of `this` when you know the number of arguments and what they are use to set the value of `this` when you don’t know the number of arguments
  • 136. Modifying Context Taking control of this `call` `apply` `bind` use to set the value of `this` when you know the number of arguments and what they are use to set the value of `this` when you don’t know the number of arguments use to set the value of `this` but without executing the function
  • 138. function getEventListener(sniffer) { function on(event, callback) { window.addEventListener(event, callback); } if (sniffer.isIE()) { function on(event, callback) { window.attachEvent(event, callback); } } return on; } var browserSniffer = { isIE: function () { return false; } }; getEventListener(browserSniffer).toString();
  • 139. function getEventListener(sniffer) { function on(event, callback) { window.addEventListener(event, callback); } if (sniffer.isIE()) { function on(event, callback) { window.attachEvent(event, callback); } } return on; } var browserSniffer = { isIE: function () { return false; } }; getEventListener(browserSniffer).toString();
  • 140. function getEventListener(sniffer) { function on(event, callback) { window.addEventListener(event, callback); } if (sniffer.isIE()) { function on(event, callback) { window.attachEvent(event, callback); } } return on; } var browserSniffer = { isIE: function () { return false; } }; getEventListener(browserSniffer).toString();
  • 141. function getEventListener(sniffer) { function on(event, callback) { window.addEventListener(event, callback); } if (sniffer.isIE()) { function on(event, callback) { window.attachEvent(event, callback); } } return on; } var browserSniffer = { isIE: function () { return false; } }; getEventListener(browserSniffer).toString();
  • 142. function getEventListener(sniffer) { function on(event, callback) { window.addEventListener(event, callback); } if (sniffer.isIE()) { function on(event, callback) { window.attachEvent(event, callback); } } return on; } var browserSniffer = { isIE: function () { return false; } }; getEventListener(browserSniffer).toString();
  • 143. function getEventListener(sniffer) { function on(event, callback) { window.addEventListener(event, callback); } if (sniffer.isIE()) { function on(event, callback) { window.attachEvent(event, callback); } } return on; } var browserSniffer = { isIE: function () { return false; } }; getEventListener(browserSniffer).toString(); function on(event, callback) { window.attachEvent(event, callback); }
  • 145. Encapsulation the JavaScript Way function Vault(passcode) { var locked = true, data = {}; function checkPasscode(attemptedPasscode) { return attemptedPasscode == passcode; } function grantAccess() { locked = false; return true; } this.isLocked = function () { return locked; }; this.lock = function () { locked = true; }; // ...
  • 146. Encapsulation the JavaScript Way function Vault(passcode) { var locked = true, data = {}; function checkPasscode(attemptedPasscode) { return attemptedPasscode == passcode; } function grantAccess() { locked = false; return true; } this.isLocked = function () { return locked; }; this.lock = function () { locked = true; }; // ... // ... this.unlock = function (attemptedPasscode) { checkPasscode(attemptedPasscode) && grantAccess(); }; this.store = function (key, value) { if (this.isLocked()) { throw new Error('The vault is locked'); } data[key] = value; }; this.retrieve = function (key) { if (this.isLocked) { throw new Error('The vault is locked'); } return data[key]; }; }
  • 147. $ node encapsulation.js var v = new Vault('sekret'); v.isLocked(); true v.unlock('sekret') v.store('js_functions', 'Awesome') v.retrieve(‘js_functions') Awesome v.lock() v.isLocked() true v.retrieve('js_functions') /Users/colin/Documents/talks/js_functions/encapsulation.js:40 throw new Error('The vault is locked'); ^ Error: The vault is locked at Vault.retrieve (/Users/colin/Documents/talks/js_functions/encapsulation.js:40:19) at Object.<anonymous> (/Users/colin/Documents/talks/js_functions/encapsulation.js:68:3) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3