Professional Documents
Culture Documents
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
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