You are on page 1of 39

Object‐Oriented


JavaScript
Getting
from
Scripts
to
Applications

Donald
J.
Sipe

|

Refresh
Jacksonville

|

November
11th
2008

JavaScript
Hello
World!

We
are
here

Pseudoclassical
Inheritance
JavaScript
What
we’ll
be
talking
about

OOP
Basics
 Scope
 Closures
 Context

Appling
to
OOP
 Constructors
 Methods
 Public
 Private
 Privileged

But
First...
Some
handy
tools
Here
are
some
handy
things
you
might
not
know

JavaScript
can
do:
 Object‐literal
notation
 Anonymous
functions
 Binary
assignment
 Dot‐style
and
array‐style
access
of
properties
Handy
Tools
Object
Literal
Notation—Makes
JSON
possible



//
The
old
way
var
myObject
=
new
Object();
myObject.val
=
“test”;



//
Using
object
literal
notation
var
myObject
=
{


val:
“test”
};
Handy
Tools
Object
Literal
Notation



//
The
old
way
var
myArray
=
new
Array(1,
30,
“Refresh”);



//
Using
object
literal
notation
var
myArray
=
[1,
30,
“Refresh”];
Handy
Tools
Anonymous
Functions

 In
JavaScript,
functions
are
treated
as
values,
which

means:
 Functions
can
be
assigned
to
variables
 Functions
can
be
passed
as
arguments
to
other
functions




Handy
Tools
Anonymous
Functions



//
Using
an
anonymous
function
as
an
argument
setTimeout(
function
()
{




alert(
“Refresh”
);


},
1000
);



//
Using
a
function
as
a
variable
var
myFunc
=
function
()
{



alert(
“Refresh”
);

};
setTimeout(myFunc,
1000);
Handy
Tools
Anonymous
Functions
:
Building
a
“scope
bubble”
Using
an
anonymous
function
to
wrap
code
you
don’t
want
in
the

global
scope



var
globalVar
=
“Refresh”;

//
Global
scope

//
Create
a
scope
bubble
(
function
()
{



var
privateVar
=
“Jacksonville”;



alert(
globalVar
+
“
”
+
privateVar
);

}
)();



alert
(privateVar
==
undefined);
Handy
Tools
Binary
Assignment
Set
a
default
value
only
if
the
variable
doesn’t
have
a
value
yet



//
Traditional
ternary
assignment
var
myVar
=
myVar
?
myVar
:
0;



//
Binary
assignment
var
myVar
=
myVal
||
0;
Handy
Tools
Dot‐Style
and
Array‐Style
property
access



var
sampleObj
=
{


color:
“blue”,


width:
“16px”
};



//
Traditional
dot‐style
access
alert(
sampleObj.color
==
“blue”
);



//
Alternative
array‐style
access
alert(
sampleObj[“width”]
==
“16px”
);
Back
to
OOP
Basics…

Scope,
Closures,
and
Context
Scope
 Only
functions
have
scope.

Blocks
(if,
while,
for,
switch)

do
not.

 All
variables
are
within
the
global
scope
unless
they
are

defined
within
a
function.

 All
global
variables
actually
become
properties
of
the

window
object

 When
variables
are
not
declared
using
the
var
keyword,

they
decared
globally.
Scope


var
foo
=
“orig”;

//
foo
is
now
a
global
variable



if
(
true
)
{


foo
=
“new”;

//
Global
foo
now
equals
“new”
}



//
create
function
to
modify
its
own
foo
variable
function
test
()
{


var
foo
=
“old”;
}



test();
alert(
foo
==
“new”
);

//
Global
foo
still
equals
“new”
Scope
If
you
forget
to
use
the
var
keyword
to
define
a
value
within
a

function—even
if
it’s
only
used
within
the
function—the
value

will
be
defined
globally.



var
foo
=
“new”;
alert(
foo
==
“new”
);

//
Omitting
the
var
keyword
reverts
scope
//
of
foo
to
global
level
function
badTest
()
{


foo
=
“bad
news”;
}



badTest();

//
Global
foo
now
equals
“bad
news”
alert(
foo
==
“bad
news”
);


Scope:
Inner
Func@ons
 Functions
can
be
defined
within
one
another
 Inner
functions
have
access
to
the
outer
function’s

variables
and
parameters.


function
getRandomInt(max)
{


var
randNum
=
Math.random()
*
max;



function
ceil()
{




return
Math.ceil(randNum);


}


return
ceil();

//
Notice
that
no
arguments
are
passed
}

//
Alert
random
number
between
1
and
5
alert(getRandomInt(5));
Closures
 Inner
functions
maintain
the
scope
they
enjoyed
when

their
parent
function
was
called—even
after
the
parent

function
has
terminated.

 This
allows
you
to
effectively
pass
variables
to

functions
that
may
not
be
called
for
some
time.
Closures


function
delayedAlert
(message,
delay)
{


//
Set
an
enclosed
callback


setTimeout(
function
()
{





//
Use
message
variable
passed
to
outer
function




alert(message);



},
delay);



//
Display
a
message
with
a
5
second
delay
delayedAlert(“Refresh”,
5000);
Context
 Your
code
will
always
be
running
within
the
context
of

another
object

 Context
is
maintained
through
the
use
of
the
this

variable.



function
increment()
{


this.x
=
this.x
||
0;


return
this.x++;
};



alert(
increment()
==
0
);



alert(
increment()
==
1
);
Context


var
myObject
=
{


set:
function
(newVal)
{
this.val
=
newVal;
}
};


alert(
myObject.val
==
null
);

//
val
property
not
set
yet



myObject.set(“Refresh”);
alert(
myObject.val
==
“Refresh”
);
//
val
equals
“Refresh”



//
Change
the
context
of
set()
to
the
window
object

window.set
=
myObject.set;

window.set(
“Refresh
Jacksonville”
);



alert(
myObject.val
==
“Refresh”
);



alert(
window.val
==
“Refresh
Jacksonville”
);
Context:
Changing
Contexts
JavaScript
provides
two
handy
functions
for
executing
a

function
within
the
context
of
another
function:
 call(
)
 apply(
)
Context:
Changing
Contexts
Using
call()
—
Arguments
passed
by
name



//
Simple
function
to
change
the
color
style
of
a
node
function
changeColor
(newColor)
{


this.style.color
=
newColor;
}



//
window.changeColor
has
no
style
property,
so
call
fails
changeColor(
“red”
);



//
Grab
the
DOM
node
with
the
id
“required”
var
reqField
=
document.getElementById(
“required”
);



//
Call
changeColor()
within
reqField’s
context
changeColor.call(
reqField,
“red”
);
Context:
Changing
Contexts
Using
apply()
—
Arguments
passed
as
an
array



//
Simple
function
to
change
the
color
style
of
a
node
function
changeColor
(newColor)
{


this.style.color
=
newColor;
}



//
Set
the
text
color
of
the
body
element
function
setBodyTextColor
()
{


changeColor.apply(
document.body,
arguments
);
}



setBodyTextColor(
“black”
);
Object
Oriented

Programming
Constructors
and
methods
Object
Oriented
Programming
Now
let’s
apply
all
of
this
information
to
a
more
classical

view
of
OOP
in
JavaScript:
 Constructors

 Object
Methods
 Public
 Private
 Privileged
About
Objects
 Almost
everything
written
in
JavaScript
is
an
object

 Objects
can
be
though
of
as
a
collection
of
properties
—much
like
a
hash
in
other
languages

 JavaScript
doesn’t
have
a
concept
of
classes
like
other

object‐oriented
languages

 Classes
are
simulated
using
a
concept
called
prototypal

inheritance
Constructors
Like
other
languages,
JavaScript
uses
the
new
operator
to
create

new
instances
of
objects.



//
Create
User
object
constructor
function
User
(
name
)
{


this.name
=
name;
}



//
Create
a
new
instance
of
a
User
var
me
=
new
User(“Bob”);



//
Alert
new
user’s
name
alert(
me.name
==
“Bob”
);



//
Cannot
call
User
directly
alert(
User.name
==
undefined
);
//
window.name
is
undefined
Methods

Private Privileged Public


Public
Methods
One
way
to
create
a
public
method—a
function
that
can

be
freely
reference
by
code
outside
your
object—is
to

attach
it
to
the
object’s
prototype.

An
object’s
prototype
is
a
special
property
that
acts
as
a

base
reference
of
your
object.



This
prototype
object
is
copied
and
applied
to
all
new

instances
of
your
object.
Public
Methods


//
Our
User
object
written
a
different
way
var
User
=
function
(name)
{


this.name
=
name;
}



//
Add
a
public
accessor
method
for
name
User.prototype.getName
=
function
()
{


return
this.name;
}



var
me
=
new
User(
“Bob”
);



alert(
me.getName()
==
“Bob”
);
Private
Methods

Private
methods
are
functions
that
are
only
accessible
to

methods
inside
your
object
and
cannot
be
accessed
by

external
code.
Private
Methods


//
Our
User
object
with
some
changes
var
User
=
function
(name)
{


this.name
=
name;


function
welcome
()
{




alert(
“Welcome
back,
”
+
this.name
+
“.”);


}


welcome();
}



//
Create
a
new
User

var
me
=
new
User(
“Bob”
);

//
Alerts:
“Welcome,
Bob.”

//
Fails
because
welcome
is
not
a
public
method
me.welcome();
“Privileged”
Methods
The
term
privileged
method

was
coined
by
Douglas

Crockford.

It
is
not
a
formal
construct,
but
rather
a

technique.

Privileged
methods
essentially
have
one
foot
in
the
door:
 Then
can
access
private
methods
and
values
within
the

object
 They
are
also
publicly
accessible
“Privileged”
Methods


//
Our
User
object
with
some
tweaks
var
User
=
function
(name,
age)
{



var
year
=
(new
Date()).getFullYear()
–
age;


this.getYearBorn
=
function
()
{




return
year;


};
};



//
Create
a
new
User

var
me
=
new
User(
“Bob”,
28
);



//
Access
privileged
method
to
access
private
year
value
alert(
me.getYearBorn()
==
1980
);



//
Fails
because
year
is
private
alert(
me.year
==
null
);
Grand
Finale
Using
Scope,
Closures,
Contexts,
and
what
we’ve

discussed
about
OOP,
we
can
dynamically
generate

classes
based
on
information
supplied
to
the

constructor.
Grand
Finale



//
Our
User
object
modified
to
accept
an
object
of
properties
function
User
(properties)
{


//
Loop
through
properties
and
create
getter
and
setter
methods


for
(
var
i
in
properties
)
{
function
()
{




this[“get”
+
i]
=
function
()
{







return
properties[i];




};




this[“set”
+
i]
=
function
(val)
{







properties[i]
=
val;




};


})();
}
}




//
Create
a
new
user,
automatically
creating
get
and
set
methods
var
me
=
new
User(
{


name:
“Bob”,


age:
28
});
Grand
Finale


//
…continued

//
Note
that
name
is
private
within
properties
alert(
me.name
==
null
);

//
Access
privileged
getname()
method
alert(
me.getname()
==
“Bob”
);

//
Use
the
dynamically
generated
setter

//
to
change
the
user’s
age
me.setage(21);
alert(
me.getage()
==
21
);
Ques@ons
?

References
Pro
JavaScript
Techniques,
by
John
Resig

Douglas
Crockford’s

YUI
Theater
Presentations
•
http://developer.yahoo.com/yui/theater


You might also like