3. ARE YOU CONFUSED?
I was
JavaScript is the most confusing thing I have ever tried to learn
4. JavaScript is not your parents’
programming language
No Classes
Unusual inheritance
Changing scopes
Weird object creation
Functions with
functions
Unusual variable
behavior
5. What this session isn’t
This session is not an intro to
JavaScript
You have worked with
JavaScript for a while
This session is not about
politics, muscle cars, your DVR,
or anything else you may find
confusing
7. Scoping
JavaScript Scopes !== C-Style Scopes
JavaScript does not have block scope
CFML developers are used to this
If you create a variable it does NOT live in the context of the
“block” where it was created (if, loop, etc).
The variable lives in the execution context where is was
created
Execution context was a new term for me
8. Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
9. Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
Variable created in
the global scope
10. Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
Variable from the
global scope is used
11. Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
Variable from the global
scope was updated by
doSomething()
12. var x = 1;
function doSomething() {
var x = 1;
for (i = 1; i < 10; i++) {
x += i;
}
console.log( "Function Scope Variable: " + x);
}
doSomething();
console.log( "Global Scope Scope Variable: " + x);
Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
13. var x = 1;
function doSomething() {
var x = 1;
for (i = 1; i < 10; i++) {
x += i;
}
console.log( "Function Scope Variable: " + x);
}
doSomething();
console.log( "Global Scope Scope Variable: " + x);
Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
Variable created in
the global scope
14. var x = 1;
function doSomething() {
var x = 1;
for (i = 1; i < 10; i++) {
x += i;
}
console.log( "Function Scope Variable: " + x);
}
doSomething();
console.log( "Global Scope Scope Variable: " + x);
Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
Another variable
created in the scope
of the doSomething()
function scope
15. var x = 1;
function doSomething() {
var x = 1;
for (i = 1; i < 10; i++) {
x += i;
}
console.log( "Function Scope Variable: " + x);
}
doSomething();
console.log( "Global Scope Scope Variable: " + x);
Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
The function scope
variable was changed
16. var x = 1;
function doSomething() {
var x = 1;
for (i = 1; i < 10; i++) {
x += i;
}
console.log( "Function Scope Variable: " + x);
}
doSomething();
console.log( "Global Scope Scope Variable: " + x);
Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
The global scope
variable was
unchanged
17. var x = 1;
function doSomething() {
var x = 1;
for (i = 1; i < 10; i++) {
x += i;
}
console.log( "Function Scope Variable: " + x);
}
doSomething();
console.log( "Global Scope Scope Variable: " + x);
Function Scope
JavaScript has “function scope” or “execution context”
When a variable is created, it is created in that scope
The execution context where it was created
The function in which it was created
var x = 1;
function doSomething() {
for (i = 1; i < 10; i++) {
x += i;
}
}
doSomething();
console.log(x);
19. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
20. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
Any reasonable
person would look at
this and say…
21. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
OK… I’m creating a
variable called foo
22. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
And a function called
bar()
23. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
Then I’m calling bar()
24. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
bar() checks to see if
foo is defined
25. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
If foo isn’t defined,
then it gets defined
with a value of 10
26. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
Then foo gets logged
out
27. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple exampleWell, we know foo
is defined, with a
value of 1.
28. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
So this should log a 1, right?
29. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
30. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
Wait… what?
31. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
Consider this simple example
32. So what happened?
What we just saw is confusing
Why is the value 10 and not
1?
The answer is a combination
of
Function Scope
And variable hoisting
33. So what is variable hoisting?
Function and Variable
declarations get “hoisted” to
the top of the executable
context
Functions first
Then variables
So the JavaScript engine is
rewriting our code
Let’s see how
34. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
35. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our codebar() is a function, so
it gets hoisted first to
the top of the
execution context
36. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
In the case, it is the
global context
37. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
38. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
Next our variables
get hoisted.
39. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
Next our variables
get hoisted.
Wait… did he says
“variableS”? There’s
one variable, it’s foo,
right?
40. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
41. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
So our foo variable from the
global scope got hoisted,
though not very far.
42. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
It is now at the top of the
global execution context,
below any function from the
same context.
43. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
But what’s this? Our foo
variable in the function also got
hoisted to the top of its
execution context.
44. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
So we (or at least, I) thought
that the if statement was
checking to see if the global
variable existed.
45. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
But after JavaScript’s rewrite
we see it is actually checking to
see if this variable is undefined.
!
Is it?
46. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
A variable that has not
been assigned a value is
of type undefined.
!
-MDN
47. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
So foo is undefined! It exists,
but has not been given a value
48. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
So foo receives a value of 10
because it is previously
undefined
49. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
This foo remains unchanged in
the global scope. If we were to
log again here, we’d see a 1
50. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
51. Variable Hoisting
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
bar();
JavaScript rewriting our code
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log(foo);
}
!
var foo = 1;
bar();
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log(foo);
}
!
var foo;
foo = 1;
bar();
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
52. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
53. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
We’ll make a small
change to this code
54. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
We’ll make a small
change to this code
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
55. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Did you see it?
56. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Right there. I took
out the var
57. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
So now what
happens?
58. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
59. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
60. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Exactly what we
expected to happen
the first time!
61. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Huh?
62. So why did this happen?
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It gets more confusing
var foo = 1;
function bar() {
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
63. var?
So all we did was remove var from the variable assignment
Why does that matter?
Again, this will be familiar to CFML developers
The use of var will cause the creation of the variable in the
local scope (the execution context)
Failure to use var will result in the JS engine searching
through the scope chain for the variable
If it doesn’t find the variable by the time it reaches the global
scope, it will create it there
64. var
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Let’s look at this again
65. var
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Let’s look at this again
Here we might think that the
variable will only be created if
the if statement evaluates to
true
66. var
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Let’s look at this again
var foo = 1;
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
But after that variable is
hoisted we can see that it will
exist (though it will be
undefined) regardless of the if
statement
67. var
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Let’s look at this again
var foo = 1;
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
It doesn’t matter that the
variable already exists here,
because this is in a different
scope
68. var
var foo = 1;
function bar() {
if (foo == undefined) {
var foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
Let’s look at this again
var foo = 1;
function bar() {
var foo;
if (foo == undefined) {
foo = 10;
}
console.log( "Function Scope Variable: " + foo);
}
bar();
console.log( "Global Scope Variable: " + foo);
69. No var
var foo = 1;
function bar() {
foo = 10;
}
bar();
console.log( "Global Scope Variable: " + foo);
One more time
70. No var
var foo = 1;
function bar() {
foo = 10;
}
bar();
console.log( "Global Scope Variable: " + foo);
One more time
When var is not used in the
assignment, the JavaScript
engine will search for the
variable instead of creating it
71. No var
var foo = 1;
function bar() {
foo = 10;
}
bar();
console.log( "Global Scope Variable: " + foo);
One more time
First it will look in the
function context
72. No var
var foo = 1;
function bar() {
foo = 10;
}
bar();
console.log( "Global Scope Variable: " + foo);
One more time
Then it will look in the next
scope in the chain, in this case,
it is the global scope and it
will find it.
73. No var
var foo = 1;
function bar() {
foo = 10;
}
bar();
console.log( "Global Scope Variable: " + foo);
One more time
function bar() {
foo = 10;
}
bar();
console.log( "Global Scope Variable: " + foo);
It it doesn’t find it in the global
scope, it will create it there.
75. JavaScript Prototypes
Objects inherit from objects.
What could be more object
oriented than that? - Douglas
Crockford
In JavaScript objects can be
created from other objects
This can be accomplished in
several ways
Many consider it very elegant
81. Prototypal Inheritance
Creating objects that inherit from other objects
Can only be done with two object creation methods
Constructor Functions
Object.create()
Either one is acceptable, but Object.create is recommended by
many experts
Object.create() is not supported by all browsers, but that is
easily fixed with Webshim Lib or other polyfills
90. Prototypal InheritanceEvery object has a
__proto__ property
Every object has a
__proto__ property
Every object has a
__proto__ property
Every object has a
__proto__ property
Every object has a
__proto__ property
91. Prototypal InheritanceEvery object has a
__proto__ property
Every object has a
__proto__ property
Every object has a
__proto__ property
Every object has a
__proto__ property
Every object has a
__proto__ property
In modern browsers
93. __proto__
__proto__ should NEVER be used in production (it is
deprecated)
__proto__ is a great learning tool though
We can use __proto__ to look at an object’s prototype in the
console
You can also access an object’s prototype using
Object.getPrototypeOf(object) (using Webshim Lib to
support older browsers)
94. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
95. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Simplified example
96. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Create an object from
which we will inherit
properties and
methods
97. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Create a new object
that inherits from Car
(more on this in a bit)
98. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Assign a new property
to the new object
99. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Call an inherited
method, just to see if it
works
100. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Examine the new
object
101. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
104. Prototypal Inheritance
The result
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
105. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Our inherited
method ran
106. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Car is, indeed, the
prototype of chevette
107. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
The new object
108. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
The new motor
property of the
object
109. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
But wait… why doesn’t our
object have a wheelCount
property or a go() method?
110. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
There they are, in the
objects __proto__
property
111. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
But wait… the motor there is
null. Can we access the
wheelCount? How does
JavaScript know which motor
to use?
112. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
113. Prototypal Inheritance
When you request a property from an object:
JavaScript checks for that property in the object
If it does not exist, it checks the object’s prototype (__proto__)
If it does not exist, it checks the object’s prototype’s prototype
It continues until it reaches the top level object
This is referred to as the Prototype chain
If a property exists in more than one object in the prototype chain,
the first one JS comes across is the one it will use
115. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
So if anything requests
the motor property from
our chevette
116. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
It will find this one first
in the chain
117. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
Not this one
118. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
If chevette didn’t have
a motor property, it
would find the one in
the prototype
119. Prototypal Inheritance
var Car = {
wheelCount: 4,
motor: null,
go: function() {
console.log( "Vrooooom!!!" )
}
};
var chevette = Object.create( Car );
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( Car.isPrototypeOf( chevette ) );
console.log( chevette );
120. Functions as First Class Objects
In JavaScript, Functions are first-class objects
They can have properties and methods of their own
They can be passed as arguments
They can be returned from functions
They can be properties of other objects
121. Function Prototypes
This is where things get confusing
As we know, all objects have a prototype
That prototype is store internally in __proto__
Function Objects also have a prototype property, which we’ll refer
to as the ‘Function Prototype’
The function prototype is NOT the function’s prototype (confused
yet?)
The function object still has a __proto__ that contains its prototype
122. Function Prototypes
This is where things get confusing
As we know, all objects have a prototype
That prototype is store internally in __proto__
Function Objects also have a prototype property, which we’ll refer
to as the ‘Function Prototype’
The function prototype is NOT the function’s prototype (confused
yet?)
The function object still has a __proto__ that contains its prototype
The function prototype is the object that
will become the __proto__ property of
any new object created from that
function if that function is used as a
constructor function
123. Function Prototypes
This is where things get confusing
As we know, all objects have a prototype
That prototype is store internally in __proto__
Function Objects also have a prototype property, which we’ll refer
to as the ‘Function Prototype’
The function prototype is NOT the function’s prototype (confused
yet?)
The function object still has a __proto__ that contains its prototype
124. Constructor Functions
Are just regular functions
When combined with the new keyword they behave differently
When used with new the function becomes a factory and
creates a brand new object
this becomes bound to the new object being created
this is then automatically return by the constructor
126. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
Just a regular
function
127. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
We then modify the
function’s prototype to
add inheritable
properties and methods
128. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
When we use the new
keyword to create the
object…
129. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
Our regular function
becomes a factory
function.
!
Returns this
automatically
130. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
Here is where the
difference lies
131. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
The new object does
not have Car() as its
prototype
132. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
It has Car()’s prototype
as its prototype
133. Constructor Functions
function Car() {
}
Car.prototype.wheelCount = 4;
Car.prototype.motor = null;
Car.prototype.go = function() {
console.log( 'Vroooom!!!!' );
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
!
So chevette.__proto__ == Car.prototype
135. __proto__ and prototype
Every object has a __proto__
__proto__ is a property
__proto__ references the object that is being inherited from
Only Function objects have a prototype property (in addition to
__proto__)
A Function’s prototype references the object that will become the
__proto__ property of new objects created from this function
if used as a constructor
146. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
147. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
Just a regular
function
148. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
We then modify the
function’s this object to
add properties and
methods
149. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
Remember, when we
use new, this is bound
to the new object
150. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
So hey! Look! Our new
object will have the
properties and methods,
right?
151. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
The answer isYES. But
they won’t be inherited
152. this
function Car() {
this.wheelCount = 4;
this.motor = null;
this.go = function () {
console.log( 'Vrooommmm!!!' );
}
}
var chevette = new Car();
chevette.motor = { cylinder: 4 };
chevette.go();
console.log( chevette instanceof Car );
console.log( chevette );
162. Why not use this for
everything?
When you use this new objects do not inherit those
properties and methods
They get their own copies
If you change the this scope properties or methods in the
prototype object the existing objects will not inherit the
changes
The best option is to combine prototypal inheritance with
instance variables to get what we want
163. Prototypal Inheritance
So let’s think about how Car should work
We’ll create a new object that uses inherited and instance
properties and methods to meet our needs
Car spec:
Each instance of Car should have its own name, wheelCount,
color, and motor
All instances of Car should have the same methods for go(),
addFuel(), brake(), and about()
164. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
165. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
Our Car constructor
166. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
Of course, our
constructor is only a
constructor if we
remember to use new.
167. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
Add our methods to
the Car constructor’s
prototype
168. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
This method will be
inherited from the
prototype
169. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
But when it access
the this scope it will be
getting instance variables
170. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
We’ll create some new
Cars
171. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
And then do some stuff
with them
172. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
179. Back to Object.create()
We look at prototypal inheritance with Object.create()
But we didn’t look at instance variables
180. Back to Object.create()
We look at prototypal inheritance with Object.create()
But we didn’t look at instance variables
Let’s see how our Car example might look with instance
variables
181. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
182. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
Simple object with
methods to be inherited
183. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
Use Object.create to
create new objects that
inherit from Car
184. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
One way of getting
instance variables
185. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
Is with this crap
186. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
These are called
property descriptors
187. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
If you don’t explicitly specify
writable, enumerable, or
configurable, they won’t be.
188. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
So in this example, only
color can be changed after
the object is constructed
189. var Car = {
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car, {
name : { value: 'Chevette' },
wheelCount: { value: 4 },
color: { value : 'Black', writable: true },
motor: { value : { cylinders: 4 } }
}),
Object.create(Car, {
name : { value: 'F-150' },
wheelCount: { value: 4 },
color: { value : 'Red', writable: true },
motor: { value : { cylinders: 8 } }
}),
Object.create(Car, {
name : { value: 'Ram 3500' },
wheelCount: { value: 6 },
color: { value : 'Green', writable: true },
motor: { value : { cylinders: 10 } }
})
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
191. Back to Object.create()
Other than the properties being non-
writable, non-configurable, and non-
enumerable (except for color) this
works the same as the other examples
203. But wait… there’s more
We can use the same functions we were using before for
constructors with Object.create()
204. But wait… there’s more
We can use the same functions we were using before for
constructors with Object.create()
The new object will still inherit from the function prototype
205. But wait… there’s more
We can use the same functions we were using before for
constructors with Object.create()
The new object will still inherit from the function prototype
But the constructor function never actually fires, so we can’t
use it from constructing the object with instance variables
206. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
207. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
We can use a
function
208. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
And modify its
prototype
209. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
Then use
Object.create()
210. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
Note we are passing in
Car’s prototype, not Car
211. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
Car’s prototype is
where the methods we
want to inherit are
212. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
Unfortunately, the
constructor never runs,
these variables are not
added as instance variables
213. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and
' + this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype),
Object.create(Car.prototype),
Object.create(Car.prototype)
];
console.log(cars);
218. function Car() {}
Car.prototype.init = function (name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
return this;
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype).init('Chevette', 4, 'Black', 4),
Object.create(Car.prototype).init('F-150', 4, 'Red', 8),
Object.create(Car.prototype).init('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
219. function Car() {}
Car.prototype.init = function (name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
return this;
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype).init('Chevette', 4, 'Black', 4),
Object.create(Car.prototype).init('F-150', 4, 'Red', 8),
Object.create(Car.prototype).init('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
We could use property
descriptors again… but
who’d want to?
220. function Car() {}
Car.prototype.init = function (name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
return this;
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype).init('Chevette', 4, 'Black', 4),
Object.create(Car.prototype).init('F-150', 4, 'Red', 8),
Object.create(Car.prototype).init('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
We can use an init()
method again
221. function Car() {}
Car.prototype.init = function (name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
return this;
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype).init('Chevette', 4, 'Black', 4),
Object.create(Car.prototype).init('F-150', 4, 'Red', 8),
Object.create(Car.prototype).init('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
Then call it like we did
before after passing the
function prototype into
Object.create()
222. function Car() {}
Car.prototype.init = function (name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
return this;
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
var cars = [
Object.create(Car.prototype).init('Chevette', 4, 'Black', 4),
Object.create(Car.prototype).init('F-150', 4, 'Red', 8),
Object.create(Car.prototype).init('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
223. So???
So which one should I use?!?!?!
I bet you were hoping for an answer
A lot of experts will tell you to use Object.create(). But which way
should you use Object.create()?
Some will tell you that new is evil, others will tell you the truth. new is
not evil
Pick one way and stick with it
My preference is for Object.create(SimpleObject).init() or new
ConstructorFunction()
224. var Car = {
init : function (name, wheelCount, color, cylinders) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : cylinders };
return this;
},
go : function () {
console.log( 'Vrooommmm!!!' );
},
addFuel : function () {
console.log( 'Fuel Added' );
},
brake : function () {
console.log( 'Braking' );
},
about : function() {
return 'The ' + this.name + ' has a ' + this.motor.cylinders + ' cylinder motor and '
+ this.wheelCount + ' wheels. ' + 'This one is ' + this.color;
}
}
var cars = [
Object.create(Car).init('Chevette', 4, 'Black', 4),
Object.create(Car).init('F-150', 4, 'Red', 8),
Object.create(Car).init('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel(); cars[car].go(); cars[car].brake();
}
Object.create(SimpleObject).init()
225. function Car(name, wheelCount, color, motorSize) {
this.name = name;
this.wheelCount = wheelCount;
this.color = color;
this.motor = { cylinders : motorSize };
}
Car.prototype.go = function () {
console.log( 'Vrooommmm!!!' );
};
Car.prototype.addFuel = function () {
console.log( 'Fuel Added' );
};
Car.prototype.brake = function () {
console.log( 'Braking' );
};
Car.prototype.about = function() {
return 'The ' +
this.name + ' has a ' +
this.motor.cylinders + ' cylinder motor and ' +
this.wheelCount + ' wheels. ' +
'This one is ' + this.color;
}
var cars = [
new Car('Chevette', 4, 'Black', 4),
new Car('F-150', 4, 'Red', 8),
new Car('Ram 3500', 6, 'Green', 10)
];
for (var car in cars) {
console.log(cars[car].about());
cars[car].addFuel();
cars[car].go();
cars[car].brake();
}
new ConstructorFunction()
226. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
227. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
The makeAdder() function
will create and a return a
new function
228. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
Normally we would expect
that when this function
finishes running…
229. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
… that its scope would no
longer exist, including the
howMuch argument
230. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
When we call makeAdder()
231. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
howMuch is equal to 5
232. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
The function then returns
another function (but does not
execute it)
233. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
So how then, does howMuch
still exist when …
234. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
We call the new function
235. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
Because the returned
function is a closure
236. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
Not only does it have
access to its own scope,
where addTo exists
237. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
It has access to the scope
that it was in when it was
created
238. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
Where howMuch exists and is
equal to 5
239. Closure Example
function makeAdder(howMuch) {
return function (addTo) {
return addTo + howMuch;
}
}
//Make a 5 adder
var add5 = makeAdder(5);
//Make a 10 adder
var add10 = makeAdder(10);
console.log( add5(10) ); // 15
console.log( add10(20) ); //30
240. Closures
In basic terms, a Closure is a function that maintains the
context in which is was created in addition to its own
I am not going to delve deeply into closures, Adam will do that
later