2. Agenda
• Short
Recap
of
JS
• About
EcmaScript
5
• JavaScript
Best
Prac>ces
and
Pa?erns
• JavaScript
Object
Oriented
Programming
• HTML5
and
JavaScript
• JS
–
libraries
– JQuery,
YUI
Library
-‐>
AngularJS
• Asynchronous
Module
Defini>on
(AMD)
• Designing
JS
Libraries
• Tes>ng
&
Op>mizing
3. Recommended
Reading
• Recommended
reading
– JavaScript:
The
Good
Parts
by
Douglas
Crockford
– JavaScript:
The
Definite
Guide
by
David
Flanagan
– JavaScript
Pa?erns:
Stoyan
Stefanov
• And
Google..
• Lot
of
good
presenta>ons
– http://yuilibrary.com/theater/
4. Rise
of
the
Responsive
Single
Page
App
Image:
h?p://johnpolacek.github.io/scrolldeck.js/decks/responsive/
5. Single-‐page
Applica>ons
(SPA)
• Web
app
that
fits
on
a
single
web
page
– Fluid
UX,
like
desktop
app
– Examples
like
Gmail,
Google
maps
• Html
page
contains
mini-‐views
(HTML
Fragments)
that
can
be
loaded
in
the
background
• No
reloading
of
the
page,
be5er
UX
• Requires
handling
of
browser
history,
naviga<on
and
bookmarks
6. JavaScript
• SPAs
are
implemented
using
JavaScript
and
HTML
• ECMAScript
is
a
scrip>ng
language,
standardized
by
Ecma
Interna>onal
• In
Browsers,
ECMAScript
is
commonly
called
JavaScript
– JavaScript
=
Na<ve
(EcmaScript)
+
Host
objects
(browser)
7. Not
just
Web!
• Mobile
Applica>ons
• Windows
8/10
apps
• Desktop
widgets
• Server
side
JS
10. Basic
Types
• JavaScript
is
loosely
typed
language!
• Seven
data
types
– Boolean
– null
– Undefined
– Number
• 64
bit
floa>ng
point,
also
available
Number.MAX_VALUE,
Number.MIN_VALUE
– String
– Object
11. About
Numbers
• Number(value),
converts
en>re
string
– var i = Number("12");
• parseInt(value[, radix]),
converts
start
of
the
string
– var i = parseInt("12px", 10);
– Radix?
• 10
=>
integer
number,
8
=>
octal
number,
16
=>
hexadecimal
• While
this
parameter
is
op>onal,
always
specify
it
to
eliminate
reader
confusion
and
to
guarantee
predictable
behavior.
Different
implementa<ons
produce
different
results
when
a
radix
is
not
specified.
• NaN
(Not
a
Number)
– Result
of
erroneous
opera>ons
12. var integer1 = Number("12");
var integer2 = parseInt("12", 10);
print(integer1 + integer2); // 24
var a = parseInt("12foobar", 10);
print(a); // 12
var b = parseInt(" 12 ", 10);
print(b); // 12
var c = parseInt("foobar12", 10);
print(c);
// Don't do this
if(c == NaN)
{
print("A) It's Nan!");
}
if(isNaN(c))
{
print("B) It's NaN!");
}
13. Math
Object
• All
proper>es
and
methods
are
"sta>c",
just
like
in
Java
– abs
– acos
– atan
– …
– sin
– sqrt
• var value = Math.sqrt(4);
14. Strings
• Sequences
of
0
–
n
of
16-‐bit
chars
• Example
var s1 = "Hello";
var s2 = "Hello";
if(s1 === s2)
{
print("the same!");
}
print(s1.length);
print("hello" + 12);
print(12 + "hello");
print("hello".toUpperCase());
15. True
or
false?
var myArray1 = [false, null, undefined, "", 0,
NaN];
// EcmaScript 5 feature!
// Iterate the array
myArray1.forEach(function(entry)
{
if(entry)
{
print(entry); // Here?
}
});
16. True
or
false?
var myArray1 = ["false", "0", "undefined", "NaN"];
// EcmaScript 5 feature!
// Iterate the array
myArray1.forEach(function(entry)
{
if(entry)
{
print(entry);
}
});
18. Statements
• Same
than
in
other
languages
– If
– Switch/case
– While
– Do/while
– For
– Break
– Con>nue
– Return
– Try/throw/catch
19. Rhino
(JavaScript
Engine)
• Open
Source
JS
Engine
developed
in
Java
– Mozilla
Founda>on
• No
built
in
support
for
web
browser
objects
• Has
Rhino
shell
for
running
JS
in
command
line
• Is
bundled
in
Java
SE
6
• Supports
EcmaScript
5
22. EcmaScript
• Ecma
Standard
is
based
on
JavaScript
(Netscape)
and
JScript
(Microsom)
• Development
of
the
standard
started
in
1996
• First
edi>on
1997
• Support
– http://kangax.github.com/es5-compat-table/
• Newest
version:
EcmaScript
5.1
– http://www.ecma-international.org/
publications/files/ECMA-ST/Ecma-262.pdf
23. Recap:
object
types
• Na>ve
(Core
Javascript)
– ECMAScript
standard:
Array,
Date..
• Host
– The
host
environment,
for
example
browser:
window,
DOM
objects
24. EcmaScript
• Goal
– Fix
“bad”
parts
of
JS
while
maintaining
compa>ble
with
EcmaScript
5
• Introduces
Strict
mode
– Removes
features
from
the
language!
Raises
errors
that
were
okay
in
non
strict
mode
– Backward
compa>ble
– Add
“use
strict”,
in
func>on
or
global
scope
• EcmaScript
supports
non-‐strict
mode,
but
it’s
depricated!
25. Strict
“mode”
• Detec>on
of
bad/dangerous
programming
prac>ces
– with()
statement
prevented
– Assignment
to
non-‐declared
variables
prevented
(i
=
3)
– Eval
is
prohibited
– Lot
of
other
issues..
• See
ES5
specifica>on
page
235
26. Enable
strict
mode
> cat strictmode.js
// This is just a string, backward compatible!
"use strict";
i = 0;
> rhino strictmode.js
js: uncaught JavaScript runtime exception:
ReferenceError: Assignment to undefined "i" in
strict mode
27. Global
and
local
// GLOBAL, everything is strict:
"use strict";
//.. strict program
// LOCAL, function is strict
function foo()
{
"use strict";
//.. strict function
}
28. Other
Main
Changes
• Na>ve
JSON
object
added
– For
parsing/stringifying
JSON
• Changes
to
Array
object,
nine
new
methods
– indexOf,
lastIndexOf,
every,
some,
forEach,
map,
filter,
reduce,
reduceRight
• Changes
to
Object
– Can
define
ge?ers
and
se?ers
– Objects
can
be
sealed
(no
new
proper>es
can
be
added)
and
frozen
(values
cannot
be
changed)
29. JSON
and
Weather
Underground
myObject = JSON.parse(httpObj.responseText);
city = myObject.location.city;
now = myObject.forecast.txt_forecast.forecastday[0].fcttext_metric;
icon = myObject.forecast.txt_forecast.forecastday[0].icon_url;
31. every
and
some
// Checks all the values, if one of them does not
// match with given condition, return value is false.
var returnValue = arr.every(function (value, index, array)
{
return value.length > 1;
}
);
print(returnValue); // true
// Checks all the values, if one of them matches with
// given condition, return value is true.
var returnValue = arr.some(function (value, index, array)
{
return value === "apple";
}
);
print(returnValue); // true
32. map
and
filter
// Adds Hello to the end of the array values
var newArray = arr.map(function (value, index, array) {
return value + " Hello";
});
newArray.forEach(function (entry)
{
print(entry)
}
);
// Keep only Apples.
var newArray2 = arr.filter(function (value, index, array) {
return value === "apple";
});
newArray2.forEach(function (entry)
{
print(entry)
}
);
35. Prevent
Extensions
"use strict";
var obj = {};
obj.name = "John";
print(obj.name); // "John"
print(Object.isExtensible(obj)); // true
Object.preventExtensions(obj);
// Should be exception in strict mode
obj.url = "http://www.something.com";
print(Object.isExtensible(obj));
36. Proper>es
and
Descriptors
• It’s
possible
to
define
proper>es
for
object
– Property
descriptor
• Value
• Get
and
Set
methods
• Writable
• Enumerable
• Configurable
37. Example
var obj = {};
obj.name = "something";
Object.defineProperty( obj, "name", {
value: "something", // Notice: you cannot have value and get + set
get: someFunction,
set: someOtherFunction,
writable: false, // property cannot be changed
enumerable: true, // will be iterated in for in
configurable: true // can be deleted
});
print( obj.name )
38. Sealing
and
Frozing
• Sealing
prevents
other
code
from
dele>ng
or
adding
descriptors
– Object.seal(obj)
– Object.isSealed(obj)
• Frozing
is
almost
iden>cal
to
sealing,
but
addi>on
of
making
the
proper>es
uneditable
– Object.freeze(obj)
– Object.isFrozen(obj)
39. EcmaScript
5
-‐
Overview
• Strict
Mode
• JSON
parsing
now
standard
• New
Array
methods
• New
Object
methods
42. Tools
• IDEs
– Visual
Studio,
Aptana,
Webstorm,
IxEdit
…
– Or
just
text
editor
• JS
Engines:
V8,
Rhino
..
• Quality:
JSLint
• Lot
of
frameworks
available!
43. JS
and
OO
• JavaScript
supports
object-‐oriented
language!
• Only
five
primi>ve
types:
number,
string,
boolean,
null,
undefined
– Object
wrappers
for
number,
string
and
boolean
available
• Object
is
just
a
collec>on
of
named
proper>es,
a
list
of
key-‐value
pairs
– Some
of
the
proper>es
can
be
func>ons!
• No
classes!
Let’s
look
at
OO
later
in
more
carefully.
44. JS
and
Command
Line
• It’s
possible
to
run
your
js
apps
in
command
line.
• Several
JS
engines
– SpiderMonkey
(c++)
or
Rhino
(java)
(Firefox)
– SquirrelFish
(Apple’s
Webkit)
– V8
(Google
Chrome)
• It’s
possible
to
install
these
as
command
line
apps,
although
the
process
can
be
li?le
difficult
45. Rhino
(JavaScript
Engine)
• Open
Source
JS
Engine
developed
in
Java
– Mozilla
Founda>on
• No
built
in
support
for
web
browser
objects
• Has
Rhino
shell
for
running
JS
in
command
line
• Is
bundled
in
Java
SE
6
– In
Java
8
a
new
JS
engine
called
Nashorn
47. V8
• Open
source
JS
engine
developed
by
Google
• Compiles
JS
to
na>ve
code
• Wri?en
in
C++,
runs
on
Windows,
OS
X
and
Linux
• Can
be
used
in
browser
and
standalone
engine
• You
need
to
build
the
V8
– h?p://code.google.com/p/v8/
– h?ps://developers.google.com/v8/build
49. Any
problems
in
the
code?
function sum (a, b)
{
s = a + b;
return s;
}
x = sum(5,5);
// Rhino's way to print to console
print (x);
50. JSLint
• JSLint
is
JS
code
quality
tool
made
by
Douglas
Crockford
– h?p://jslint.com
• Inspects
and
warns
about
poten>al
problems
• “Will
hurt
your
feelings”
• Excepts
that
your
code
is
in
“strict
mode”
• Can
be
used
via
website
or
command
line
(installa>on
required)
• Command
line
tool
(Java
wrapper
for
JSLint)
– h?p://code.google.com/p/jslint4java/
52. JSLint
in
Command
Line
• JSLint4java
–
Java
wrapper
for
the
JSLint
– h?p://code.google.com/p/jslint4java/
• To
use
it:
– java
-‐jar
jslint4java-‐2.0.3.jar
applica>on.js
54. Amer
some
modifica>ons
function sum(a, b) {
"use strict";
var s = a + b;
return s;
}
var x = sum(5, 5);
// Rhino's way to print to console
print(x);
59. Prin>ng
to
Console
• Debugging
in
Browsers:
use
console
–
object
• Firefox
– Firebug
extension
• Safari
– Enable
developer
mode
• How?
– console.log(“Hello
World!”);
61. Global
Variables
• Every
JS
environment
has
a
global
object
• Every
global
variable
becomes
a
property
of
the
global
object
– In
browser
environment:
window
is
the
global
object
itself
62. Declaring
Global
variable
// global object, window, will get a new property!
variable = "hi there!";
console.log(variable);
// And different ways to access the variable
console.log(window.variable);
console.log(window.variable);
console.log(window["variable"]);
console.log(this.variable);
console.log(window);
64. Problems
• Global
variables
shared
among
all
the
code
• What
if
you
use
some
third
party
JavaScript
Library
like
JQuery
or
Modernizr?
Name
collision!
• Avoid
Globals!
65. Problem
1
function something() {
// window object now has variable property!
variable = "hi there!";
}
something();
// prints "hi there!"
console.log(variable);
66. Problem
2
function something() {
// window object now has z property!
var x = z = "hello";
}
something();
// prints "hello"
console.log(z);
67. Difference
when
using
var
var x = 20;
y = 21;
console.log(window.x); // 20
console.log(window.y); // 21
delete x; // does not delete anything
delete y; // removes the y from window
console.log(window.x); // 20
console.log(window.y); // undefined
68. Using
var
• Use
always
var!
• In
strict
mode,
assignments
to
undeclared
variables
will
throw
an
error!
69. Func>ons
and
Variable
Declaring
var x = 10;
function test() {
console.log(x); // outputs what?
if(true) {
var x = 5;
}
}
test();
70. What
really
happens
var x = 10;
function test() {
var x;
console.log(x); // outputs “undefined”
if(true) {
x = 5;
}
}
test();
71. Variable
Hois>ng
• When
you
declare
a
variable
inside
a
func>on,
it
acts
like
it
was
declared
at
the
top
of
the
func>on!
• Declare
always
your
variables
at
the
top!
72. Single
Var
Pa?ern
function test() {
var a = 1,
b = 2,
…;
// rest of the function
}
test();
73. FD,
FE,
NFE
• It
gets
harder
when
a
variable
is
– Func>on
declara>on
(FD)
– Func>on
expression
(FE)
• Rules
– Func<on
declara<on
is
not
hoisted
– Func<on
expression
is
hoisted
74. Func>on
Declara>on:
this
works!
function testC()
{
print(foo());
function foo()
{
return 5;
}
}
<=>
function testD()
{
function foo()
{
return 5;
}
print(foo());
}
75. Func>on
Expression:
this
does
not
work!
function testA()
{
print(foo());
var foo = function()
{
return 5;
}
}
<=>
function testB()
{
var foo;
print(foo());
foo = function()
{
return 5;
}
}
76. Named
Func>on
Expression
// Named function expression for recursion or debugging
var somethingFoo = function somethingBar()
{
print("do something");
// Recursion, does not end well here.
somethingBar();
}
somethingFoo();
// this does not work
somethingBar();
77. Func>ons
in
if-‐statements
• In
strict
mode
code,
func:ons
can
only
be
declared
at
top
level
or
immediately
within
another
func:on.
• So
what
happens
in
non-‐strict
mode?
78. Func>ons
in
if-‐statements
function init()
{
if(true)
{
function foo() { return 1; }
}
else
{
function foo() { return 2; }
}
return foo();
}
print(init()); // 1 or 2?
80. For
loops
for(var i = 0; i < somearray.length; i++) {
doSomething();
}
<=>
var max = somearray.length;_for(var i = 0; i < max; i++) {
doSomething()
}
82. eval()
• eval()
func>on
takes
JS
(string)
and
executes
it.
• Security
issues:
don’t
use
it!
• To
parse
JSON
objects,
use
JSON.parse();
83. with
// Instead of doing this, you could…
myobj.prop.subprop.subsubprop.a = true;
myobj.prop.subprop.subsubprop.b = false;
// .. Use shortcut using with.. But DON’T!
with(myobj.prop.subprop.subsubprop)
{
a = true;
b = true;
}
// It’s confusing, just use
var s = myobj.prop.subprop.subsubprop;
s.a = true;
s.b = true;
84. Constructors
function Person(name) {
this.name = name;
}
// Should be used
var jaska = new Person("Jaska");
// Don't! Now this is bound to global object
var jeppe = Person("Jeppe");
85. Be?er
version
function Person(name) {
// If this refers not to Person (for example global object)
if(!(this instanceof Person))
{
// Let's then use the new word
return new Person(name);
}
else
{
this.name = name;
}
}
// Now both work
var vilma = new Person("Vilma");
var jaska = Person(”Jaska");
86. Code
Style
• Indenta>on:
4
spaces
(default
for
JSLint)
• Use
always
curly
braces
• Naming
conven>ons:
– Use
capital
le?er
in
constructor
func>ons:
– var
jack
=
new
Person();
87. Documen>ng
your
code
• It’s
possible
to
generate
documenta>on
from
your
comments
(like
Javadoc
in
Java)
• Free
tools
like
– JSDoc3
• h?p://usejsdoc.org/about-‐gezng-‐started.html
88. Minimizing
your
code
• The
Closure
Compiler
is
a
tool
for
making
JavaScript
download
and
run
faster
• Google
Closure
Compiler
– h?ps://developers.google.com/closure/compiler/
• Can
be
user
by
command
line
or
web
– h?p://closure-‐compiler.appspot.com/home
92. HTML5
• Fimh
version
of
HTML
standard
by
W3C
• S>ll
under
development
but
lot
of
browsers
support
the
proposal
of
the
standard
• Simple
markup
that
can
be
wri?en
either
in
HTML
or
XHTML
syntax
• Poten>al
candidate
for
cross
plahorm
mobile
apps
• Mostly
about
seman<cs,
most
of
the
cool
parts
are
implemented
using
JavaScript
• JS
APIs
are
not
part
of
HTML5,
developed
separately
94. New
JS
APIs
• Web
Storage
– The
ability
to
store
data
locally
in
browser
– Session
storage
and
local
storage
• Geoloca<on
API
– Fetching
GPS
loca>on
• File
API
– Reading
local
files
– See:
h?p://www.html5rocks.com/en/tutorials/file/dndfiles/
or
– h?ps://developer.mozilla.org/en-‐US/docs/Using_files_from_web_applica>ons
• Web
Workers
– Asynchronous
methods
• Web
Sockets
– Connec>ng
in
real>me
between
client
and
server.
Mul>player
games,
chat,
real>me
upda>ng.
Needs
server
support
– h?p://www.developerfusion.com/ar>cle/143158/an-‐introduc>on-‐to-‐websockets/
• Canvas
95. Geoloca>on
API
• Geoloca>on
API
Specifica>on
– h?p://dev.w3.org/geo/api/spec-‐source.html
• To
detect
the
loca>on
of
the
client
• In
mobile:
GPS,
in
desktop
IP-‐address
or
Wi-‐Fi
loca>on
96. function setText(val, e) {
document.getElementById(e).value = val;
}
function insertText(val, e) {
document.getElementById(e).value += val;
}
var nav = null;
function requestPosition() {
if (nav == null) {
nav = window.navigator;
}
if (nav != null) {
var geoloc = nav.geolocation;
if (geoloc != null) {
geoloc.getCurrentPosition(successCallback);
}
else {
alert("geolocation not supported");
}
}
else {
alert("Navigator not found");
}
}
function successCallback(position)
{
alert("" + position.coords.latitude + ", " + position.coords.longitude);
}
97. Showing
Map
on
Google
API
• h?p://maps.googleapis.com/maps/api/
sta>cmap?
center=<la>tude>,<longitude>&zoom=10&siz
e=200x200&maptype=roadmap
• See:
– h?ps://developers.google.com/maps/
documenta>on/sta>cmaps/
98. Wunderground
+
Geoloca>on
+
Google
sta>c
map
• Wunderground
provides
JSON
API
for
weather
informa>on
• Get
loca>on
of
the
browser
and
AJAX
request
to
wunderground
• Amer
receiving
the
result,
parse
it
and
show
results
in
html.
• Problem:
AJAX
does
not
work
cross
site..
You
can
implement
middleware
(PHP)
101. Canvas
• “The
canvas
element
a
resolu:on-‐dependent
bitmap
canvas,
which
can
be
used
for
dynamically
rendering
of
images
such
as
game
graphics,
graphs,
or
other
images”
• Image
is
drawn
in
JavaScript
using
typical
vector
graphics
drawing
primi>ves
– drawImage(),
lineTo(),
arcTo(),
bezierCurveTo(),
fillRect(),
scale(),
rotate(),
translate(),
createLinearGradient(),
shadowBlur(),
…
102. Simple
Drawing
using
Canvas
and
JS
<canvas id="mycanvas" width="200" height="200">
</canvas>
<script>
var canvas= document.getElementById('mycanvas');
var context = canvas.getContext('2d');
context.fillRect(60,30,80,120);
</script>
105. main
function main() {
createCanvas();
// Original position
reset();
// Millisecs elapsed since 1970.
then = Date.now();
loadImages();
setEventListeners();
//The setInterval() method calls a function or evaluates an expression at
//specified intervals (in milliseconds).
setInterval(gameLoop, 1);
}
window.onload=function(){
main();
}
106. Game
Objects
and
Global
Variables
var keysDown = {};
var bgImage = null;
var canvas = null;
var ctx = null;
var then;
var monstersCaught = 0;
// Game objects
var hero = {
speed: 256,
x: 0,
y: 0,
myImage: null
};
var monster = {
x: 0,
y: 0,
myImage: null
};
107. Game
Loop
function gameLoop () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
render();
then = now;
};
108. Create
Canvas
function createCanvas() {
// Create canvas element
canvas = document.createElement("canvas");
// Get the canvas object that you can use to draw
ctx = canvas.getContext("2d");
// Set size for the canvas object
canvas.width = 512;
canvas.height = 480;
document.getElementById("here").appendChild(canvas);
}
109. Star>ng
point
function reset() {
hero.x = canvas.width / 2;
hero.y = canvas.height / 2;
// Throw the monster somewhere on the screen randomly
monster.x = 32 + (Math.random() * (canvas.width - 64));
monster.y = 32 + (Math.random() * (canvas.height - 64));
};
110. Load
Image
function loadImage(imageSrc) {
var image = new Image();
image.src = imageSrc;
return image;
}
function loadImages() {
hero.myImage = loadImage("lib/hero.png");
monster.myImage = loadImage("lib/monster.png");
bgImage = loadImage("lib/background.jpg");
}
111. Key
Listeners
function setEventListeners() {
// If keydown, then add the key to the array and set it true
addEventListener("keydown", function (e) {
keysDown[e.keyCode] = true;
}, false);
// If keyup, remove it from the array
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode];
}, false);
}
112. Update
function update (modifier) {
if (38 in keysDown) { // Player holding up
hero.y -= hero.speed * modifier;
}
if (40 in keysDown) { // Player holding down
hero.y += hero.speed * modifier;
}
if (37 in keysDown) { // Player holding left
hero.x -= hero.speed * modifier;
}
if (39 in keysDown) { // Player holding right
hero.x += hero.speed * modifier;
}
// Are they touching?
if (
hero.x <= (monster.x + 32)
&& monster.x <= (hero.x + 32)
&& hero.y <= (monster.y + 32)
&& monster.y <= (hero.y + 32)
) {
++monstersCaught;
reset();
}
};
116. About
Objects
• Everything
(except
basic
types)
are
objects
– Including
func>ons
and
arrays
• Object
contains
proper>es
and
methods
– Collec>on
of
name-‐value
pairs
– Names
are
strings,
values
can
be
anything
– Proper>es
and
methods
can
be
added
at
run>me
• Objects
can
inherit
other
objects
117. Object
Literal
var mystring = "hello!";
var myarray = ["element1", "element2"];
var circle1 = {radius: 9, getArea : someFunction };
var circle2 = {
radius: 9,
getRadius: function() {
return this.radius;
}
}
118. No
Classes!
• One
of
the
simplest
way
to
create
object
– var obj = new Object();
– obj.x = 10;
– obj.y = 12;
– obj.method = function() { … }
• This
adds
dynamically
two
proper>es
to
the
obj
–
object!
• Object
is
built
–
in
data
type
119. “Class”
• To
define
a
class,
define
a
func>on
function Foo() {
this.x = 1;
this.y = 1;
}
• var obj = new Foo();
• Internally
a
Object
is
created
120. Example
function Circle(radius)
{
this.radius = radius;
this.getArea = function()
{
return (this.radius * this.radius) * Math.PI;
};
}
var myobj = new Circle(5);
document.write(myobj.getArea());
121. About
Namespaces
• Avoid
pollu>ng
global
scope
– Use
namespaces!
– Helps
avoid
clashes
between
your
code
and
third-‐
party
libraries
• Namespaces
don’t
have
dedicated
syntax
built
into
the
language
• It’s
possible
to
get
same
benefits
by
crea>ng
single
global
object
and
add
all
other
objects
and
func>ons
to
this
object
122. Example
about
Namespaces
"use strict";
// If first operand is truthy, then the result is
// first operand, else the result is second operand
// By convention namespaces are written in capitals
var MYSPACE = MYSPACE || {};
MYSPACE.Dog = function (name) {
this.name = name;
this.getName = function () {
return name;
};
};
var spot = new MYSPACE.Dog("Spot");
print(spot.getName());
123. Arrays
• Arrays
in
JS
are
dynamic,
content
can
be
added
and
removed
• Arrays
are
also
objects
(Array
“class”
inherit
Object)
– concat(),
join(),
pop(),
push(),
slice(),
sort(),
splice()
124. Example
"use strict";
var array1 = []; // or new Array()
var array2 = ['a', 'b', 'c'];
print(array2.length);
delete array2[1];
for(var i = 0; i<array2.length; i++) {
print(array2[i]);
}
125. Func>ons
• Every
func>on
in
JS
is
Func>on
object
– Can
be
passed
as
arguments
– Can
store
name
/
value
pairs
– Can
be
anonymous
or
named
• Usage
(Don’t
use
this,
it’s
not
efficient)
– var myfunction = new Function("a","b",
"return a+b;");
– print(myfunction(3,3));
• Only
func>ons
have
scope,
regular
{blocks)
don’t
• Inner
func>on
can
have
access
to
outer
func>on’s
proper>es
and
parameters
126. Func>on
Arguments
• The
arguments
object
is
a
local
object
available
within
all
func>ons
• Each
func>on
has
access
to
special
parameter
called
arguments
– Contains
the
func<on
arguments
• It’s
an
array
like
object
(but
not
an
array)
– Only
arguments.length
available
127. Example
"use strict";
function myConcat(separator) {
var result = "";
// iterate through non-separator arguments
for (var i = 1; i < arguments.length; i++) {
result += arguments[i] + separator;
}
return result;
}
// returns "red, orange, blue, "
print(myConcat(", ", "red", "orange", "blue"));
// returns "elephant; giraffe; lion; cheetah; "
print(myConcat("; ", "elephant", "giraffe", "lion", "cheetah"));
// returns "sage. basil. oregano. pepper. parsley. "
print(myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley"));
128. Func>onal
Scoping
"use strict";
function init() {
// local variable name
var name = "Hello World";
// inner function
function displayName() {
// uses outer functions variable
print(name);
}
displayName();
}
init();
129. Returning
a
Inner
Func>on
"use strict";
function makeFunc() {
var name = "Hello World";
function displayName() {
print(name);
}
return displayName;
}
// Is “Hello World” printed?
var myFunc = makeFunc();
myFunc();
130. About
Closures
• myFunc
is
a
closure
• Special
kind
of
object
that
combines
– A
func>on
– Environment
in
which
func>on
was
created
• Environment
consists
of
any
local
variables
that
were
in-‐scope
at
the
>me
closure
was
created
• myFunc
is
a
closure
that
has
displayName
and
name
131. Private
members
with
Closures
"use strict";
function getPerson(name) {
var privateMember = "hello world!", obj;
obj = {
shout: function () {
print(name + " shouts " + privateMember);
},
say: function () {
print(name + " say " + privateMember);
}
};
return obj;
};
var person = getPerson("Jack");
// Does not work!
print(person.privateMember);
person.shout();
person.say();
132. Private
methods
with
Closures
"use strict";
var person = (function(name) {
var privateMember = "hello world!", obj;
obj = {
setName: function(myName) {
name = myName;
},
shout: function () {
print(name + " shouts " + privateMember);
},
say: function () {
print(name + " say " + privateMember);
}
};
return obj;
})();
person.setName("Jack");
person.shout();
person.say();
133. this
function foo() {
// adds prop to global object
this.prop = 12;
}
var obj = {
method: function() {
// goes to obj
this.prop = 12;
}
};
obj.method();
function Dog(name) {
// Refers to object being created!
this.name = name;
this.sayHello = function() {
print(this.name + " says hello!");
};
}
var dog = new Dog("Spot");
dog.sayHello();
136. About
Inheritance
• Code
reuse
is
important
– Inheritance
can
help
• JavaScript
does
not
have
classes,
so
no
special
keyword
for
extending
– This
can
be
very
confusing
for
Java/C#
developers
– Objects
inherit
objects
137. Understanding
JS
Inheritance
• JS
is
not
class
based,
it’s
prototype-‐based!
• Object
inherit
from
another
object
• JS
contains
syntax
and
features
that
make
it
seem
class
based
138. Understanding
Prototypes
• Prototype
is
an
object
from
which
other
objects
inherit
proper>es
• Any
object
can
be
a
prototype
• Every
object
has
internal
__proto__
property
139. Example
var parent = {
method1: function() { print("A"); }
}
var child = {
__proto__: parent,
method2: function() { print("B"); }
}
// If method1 is not found in child, look it from
// prototype!
child.method1(); // A
child.method2(); // B
140. __proto__
• __proto__
is
depricated
and
should
not
be
used
(but
it
works)
• To
get
the
prototype,
use
– Object.getPrototypeOf(object)
• It’s
read
only!
• How
to
set?
– Proposal:
Object.setPrototypeOf(obj,
prototype)
• Not
possible
to
change
the
__proto__
..!
141. Func>on
Object
• When
wri>ng
– function Animal() { }
• Lot
of
things
happens!
– Two
objects
created:
• 1)
Animal
• 2)
Animal.prototype
– Animal.prototype
has
a
property
constructor,
that
points
to
Animal
142. Func>on
Object
// This is just a function. Dog is Function object!
function Dog (name) {
this.name = (name);
}
var spot = new Dog("Spot");
// true
print(spot instanceof Object);
// true
print(Dog instanceof Function);
// true
print(Dog instanceof Object);
143. Func>on
Object
function sum1(a, b) {
return a + b;
}
// =>
var sum2 = new Function("a","b", "return a+b;");
print(sum1(2,2)); // 4
print(sum2(2,2)); // 4
print(sum2.length); // number of args = 2
print(sum2.toString());
144. The
“new”
Operator
function Person() {
this.name = “Jack”;
}
// Normal function call
Person();
// Object creation
var p = new Person();
146. Example
function Cat() { }
// c.__proto__ points to Cat.prototype!
var c = new Cat();
// true
print(c.__proto__ === Cat.prototype);
// c inherites Cat.prototype!
Cat.prototype.age = 12;
// 12!
print(c.age);
147. Example
function Cat() { this.name = "Jack"; }
var c = new Cat();
// true
print(c.__proto__ === Cat.prototype);
// c inherites Cat.prototype! Let's add stuff.
Cat.prototype.age = 12;
Cat.prototype.saySomething = function() {
print(this.name + ": hello!");
}
// 12!
print(c.age);
// "Jack: hello!"
c.saySomething();
148. /** PERSON **/
function Person() { }
var jack = new Person();
// jack inherites Person.prototype!
print(jack.__proto__ === Person.prototype);
Person.prototype.age = 18;
print(jack.age); // 18;
//** STUDENT **/
function Student() { }
// Let's now change the prototype of Student.
// Now Student.prototype points to Person.
var temp = new Person();
Student.prototype = temp;
var tina = new Student();
// tina inherites Student.prototype.. which is now temp!
print(tina.__proto__ === Student.prototype); // true
print(tina.__proto__ === temp); // true
// Now tina inherites Student.prototype, which is
// Person object, which inherites the Person.prototype..
print(tina.age); // 18!
149. Example
/** Person **/
function Person() {
this.name = "Jack";
}
// Adding functionality to the prototype..
Person.prototype.say = function() {
print(this.name + ”: hello!");
}
/** Student **/
function Student() { }
// Inheritance
Student.prototype = new Person();
/** Test **/
var student = new Student();
student.say(); // Jack: Hello
Person.prototype
say()
new
Person()
name
=
“Jack”
__proto__
150. Example
/** Person **/
function Person() {
this.name = "Jack";
}
// Adding functionality to the prototype.. What is this??
Person.prototype.say = function() {
print(this.name + ”: hello!");
}
/** Student **/
function Student() { }
// Inheritance
Student.prototype = new Person();
/** Test **/
var student = new Student();
student.say(); // Jack: Hello
Person.prototype
say()
new
Person()
name
=
“Jack”
__proto__
new
Student()
__proto__
151. Func>on
Object
• Every
func>on
in
JS
is
a
Func>on
object
• When
– var spot = new Dog(“spot”);
• Then
spot’s
__proto__
points
to
Dog.prototype!
• If
a
property
cannot
be
found
in
an
object,
it
is
searched
for
in
that
object's
prototype.
152. Example
// here's the constructor:
function Point() { }
var a = new Point();
print (a.x); // undefined
// set up the prototype object to have some values:
Point.prototype = { x: 10, y: 20 };
// or you could do this:
Point.prototype.z = 30;
// make a new Point object
// (a object gets an implicit reference to Point.prototype object)
var a = new Point();
// Since a does not hold a property, let's look it from Point.prototype
print (a.x);
153. Example
// here's the constructor:
function Point() {
this.x = 10;
this.y = 20;
}
// set up the prototype object to have some values:
Point.prototype.z = 40;
// make a new Point object
// (a object gets an implicit reference to Point.prototype object)
var a = new Point();
// Since a does not hold a property, let's look it from Point.prototype
print (a.z);
154. //** POINT **
function Point() {
}
// set up the prototype object to have some values:
Point.prototype = { x: 10, y: 20 };
/** PIXEL **/
function Pixel() {
}
Pixel.prototype = new Point();
Pixel.prototype.color = "red";
// make a new Point object
// (a object gets an implicit reference to Point.prototype object)
var a = new Pixel();
var b = new Pixel();
a.color = "blue";
// Since a does not hold a property, let's look it from Point.prototype
print (a.color);
print (b.color);
155. About
constructors
• Prototype
proper>es
of
Func>ons
have
a
constructor
property:
– var
dog
=
new
Dog();
– dog.constructor
==
Dog;
//
TRUE
• This
will
break
when
doing
inheritance!
156. /** Person **/
function Person() {
}
Person.prototype.name = "Jack";
/** Student **/
function Student() {
this.id = "12345";
}
// Inheritance
Student.prototype = new Person();
Student.prototype.id = "12345";
/** Test **/
var student = new Student();
student.age = 22;
print(student.age)
print(student.name);
print(student.id);
var person = new Person();
print(person.constructor === Person); // TRUE
var student = new Student();
print(student.constructor === Student); // FALSE
157. /** Person **/
function Person() {
}
Person.prototype.name = "Jack";
/** Student **/
function Student() {
this.id = "12345";
}
// Inheritance
Student.prototype = new Person();
Student.prototype.id = "12345";
// FIX
Student.prototype.constructor = Student;
/** Test **/
var student = new Student();
student.age = 22;
print(student.age)
print(student.name);
print(student.id);
var person = new Person();
print(person.constructor === Person); // TRUE
var student = new Student();
print(student.constructor === Student); // FALSE
158. Inheritance:
Prototypal
• In
EcmaScript
5
a
protypal
inheritance
pa?ern
is
part
of
the
language
– var child = Object.create(parent);
• The
create-‐func>on
function create(o) {
function F() {}
f.prototype = o;
return new F();
}
159. Example
function Point(x,y) {
this.x = x;
this.y = y;
}
var pixel = Object.create(new Point(12,0));
pixel.color = "red";
print(pixel.x);
print(pixel.color);
162. Intro
• Number
of
open
source
JS
libraries
– Assist
frequent
JS
programming
tasks
– Hide
browser
differences
• Lot
of
possibili>es
– Google
Web
Toolkit
– JQuery
– AngularJS
– YUI3
(not
developed
anymore)
– Modernizr
– …
164. JQuery
• Mo>va>on
– Simple
things
may
require
lot
of
coding
– Common
browsers
are
different
and
implementa>on
varies
• Solu>on,
use
a
framework
– jQuery
is
a
fast
and
concise
JavaScript
Library
that
simplifies
HTML
document
traversing,
event
handling,
anima>ng,
and
Ajax
interac>ons
for
rapid
web
development.
165. How?
• Download
JQuery
file
(h?p://jquery.com/)
– h?p://code.jquery.com/jquery-‐1.8.3.min.js
• Make
your
(x)html
page
and
reference
to
the
file
in
script
block
• Make
your
code
and
use
JQuery
func>ons!
166. <script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
// When document is ready to be manipulated
jQuery(document).ready( pageReadyToBeManipulated );
function pageReadyToBeManipulated() {
// If link is clicked
jQuery("a").click( linkClick );
}
function linkClick(event) {
alert("Thanks for visiting!");
// Prevent the default action
event.preventDefault();
}
//]]>
</script>
167. Some
Basic
Syntax
• JQuery
can
be
used
in
two
ways:
– JQuery()
– Or
– $()
• $
is
an
alias
to
JQuery()!
$
more
commonly
used
168. <script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
// When document is ready to be manipulated
$(document).ready( pageReadyToBeManipulated );
function pageReadyToBeManipulated() {
// If link is clicked
$("a").click( linkClick );
}
function linkClick(event) {
alert("Thanks for visiting!");
// Prevent the default action
event.preventDefault();
}
//]]>
</script>
170. // EVEN SHORTER SYNTAX, FORGET THE DOCUMENT PARAMETER
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
$().ready(function(){
$("a").click(function(event){
alert("Thanks for visiting!");
event.preventDefault();
});
});
//]]>
</script>
171. Ge?ers
in
the
Tradi>onal
Way
• getElementsById
• getElementsByTagName
• getAttribute
172. JQuery
and
Selectors
• Select
all
h1
elements
– $(“h1”)
• Select
the
first
one
– $(“h1”)[0]
• Add
contents
– $(“????”)[0].innerHTML
=
“hello!”;
• Lot
of
different
selectors
– h?p://api.jquery.com/category/selectors/
173. Crea>ng
Elements
in
Tradi>onal
Way
• createElement
• createTextNode
• setAttribute
• appendChild
• removeChild
178. Angular
JS
• Single
Page
App
Framework
for
JavaScript
• Implements
client-‐side
Model-‐View-‐Whatever
pa?ern
– Some
call
it
MVC,
some
MVVM,
it
does
not
ma?er:
– Separa<on
of
presenta>on
from
business
logic
and
presenta<on
state
• No
direct
DOM
manipula>on,
less
code
• Support
for
all
major
browsers
• Supported
by
Google
• Large
and
fast
growing
community
179. First
Example
–
Template
<!DOCTYPE html>
<html ng-app>
<head>
<title>
Title
</title>
<meta charset="UTF-8" />
<style media="screen"></style>
<script src="angular.min.js"></script>
</head>
<body>
<!-- initialize the app -->
<div>
<!-- store the value of input field into a variable name -->
<p>Name: <input type="text" ng-model="name"></p>
<!-- display the variable name inside (innerHTML) of p -->
<p ng-bind="name"></p>
</div>
</body>
</html>
Download
this
file
from:
https://angularjs.org/
Direc>ve
Direc>ve
Template
180. Basic
Concepts
• 1)
Templates
– HTML
with
addi>onal
markup,
direc>ves,
expressions,
filters
...
• 2)
Direc<ves
– Extend
HTML
using
ng-app,
ng-bind,
ng-model
• 3)
Filters
– Filter
the
output:
filter,
orderBy,
uppercase
• 4)
Data
Binding
– Bind
model
to
view
using
expressions
{{ }}
181. Lot
of
Built
in
Direc>ves
• ngApp
• ngClick
• ngController
• ngModel
• ngRepeat
• ngSubmit
• ngDblClick
• ngMouseEnter
• ngMouseMove
• ngMouseLeave
• ngKeyDown
• ngForm
182. 2)
Expressions
• Angular
expressions
are
JavaScript-‐like
code
snippets
that
are
usually
placed
in
bindings
– {{ expression }}.
• Valid
Expressions
– {{ 1 + 2 }}
– {{ a + b }}
– {{ items[index] }}
• Control
flow
(loops,
if)
are
not
supported!
• You
can
use
filters
to
format
or
filter
data
185. 3)
Filter
• With
filter,
you
can
format
or
filter
the
output
• Formanng
– currency, number, date, lowercase,
uppercase
• Filtering
– filter, limitTo
• Other
– orderBy, json
191. Model
–
View
-‐
Controllers
• Controllers
provide
the
logic
behind
your
app.
– So
use
controller
when
you
need
logic
behind
your
UI
• Use
ng-‐controller
to
define
the
controller
• Controller
is
a
JavaScript
Object,
created
by
standard
JS
object
constructor
192. View,
Controller
and
Scope
View
(html
fragment)
Controller
(view
agnos>c!)
$scope
$scope is
an
object
that
can
be
used
to
communicate
between
View
and
Controller
Model
193. controller.js
// Angular will inject the $scope object, you don't have to
// worry about it! By using $scope, you can send data to
// view (html fragment)
function NumberCtrl ($scope) {
// $scope is bound to view, so communication
// to view is done using the $scope
$scope.number = 1;
$scope.showNumber = function showNumber() {
window.alert( "your number = " + $scope.number );
};
}
Warning,
this
will
not
work
from
AngularJS
1.3.
We
will
see
later
on
how
this
is
done
using
module
195. When
to
use
Controllers
• Use
controllers
– set
up
the
ini>al
state
of
$scope
object
– add
behavior
to
the
$scope
object
• Do
not
– Manipulate
DOM
(use
data-‐binding,
direc<ves)
– Format
input
(use
form
controls)
– Filter
output
(use
filters)
– Share
code
or
state
(use
services)
197. Modules
• Module
is
an
reusable
container
for
different
features
of
your
app
– Controllers,
services,
filters,
direc>ves...
• All
app
controllers
should
belong
to
a
module!
– More
readability,
global
namespace
clean
• Modules
can
be
loaded
in
any
order
• We
can
build
our
own
filters
and
direc<ves!
198. Example:
Own
Filter
// declare a module
var myAppModule = angular.module('myApp', []);
// configure the module.
// in this example we will create a greeting filter
myAppModule.filter('greet', function() {
return function(name) {
return 'Hello, ' + name + '!';
};
});
199. HTML
using
the
Filter
// We will use module myApp
<div ng-app="myApp">
<div>
{{ 'World' | greet }}
</div>
</div>
200. angular.module
• The
angular.module
is
a
global
place
for
crea>ng,
registering
and
retrieving
Angular
modules
• Crea>ng
a
new
module
– var myModule = angular.module('myMod', []);
• The
second
argument
([])
defines
dependent
modules
–
which
modules
should
be
loaded
first
before
this
201. Template
for
Controllers
// Create new module 'myApp' using angular.module method.
// The module is not dependent on any other module
var myModule = angular.module('myModule',
[]);
myModule.controller('MyCtrl', function ($scope) {
// Your controller code here!
});
202. Crea>ng
a
Controller
in
Module
var myModule = angular.module('myModule',
[]);
myModule.controller('MyCtrl', function ($scope) {
var model = { "firstname": "Jack",
"lastname": "Smith" };
$scope.model = model;
$scope.click = function() {
alert($scope.model.firstname);
};
});
203. <!DOCTYPE html>
<html>
<head>
<title>Title</title>
<meta charset="UTF-8" />
<style media="screen"></style>
<script src="../angular.min.js"></script>
<script src="mymodule.js"></script>
</head>
<body>
<div ng-app="myModule"
<div ng-controller="MyCtrl">
<p>Firstname: <input type="text" ng-model="model.firstname"></p>
<p>Lastname: <input type="text" ng-model="model.lastname"></p>
<p>{{model.firstname + " " + model.lastname}}</p>
<button ng-click="click()">Show First name</button>
</div>
</div>
</body>
</html>
This
is
now
the
model
object
from
MyCtrl.
Model
object
is
shared
with
view
and
controller
206. AMD
• JavaScript
does
not
have
"classes"
or
"packages"
or
"import"
• Asynchronous
Module
Defini<on
(AMD)
is
a
JS
specifica>on
that
defines
API
for
defining
code
in
modules
– Load
smaller
JS
files,
only
when
needed
– Allow
developers
define
dependencies
– Encapsula>on
• Specifica>on
is
implemented
by
RequireJS
and
ScriptManJS
• Specifica>on:
– https://github.com/amdjs/amdjs-api/blob/master/AMD.md
• Different
JS
libraries
support
AMD
spec
– RequireJS,
curl,
lsjs
and
Dojo
207. Problem
• Gezng
mul>ple
files
onto
a
page
is
to
include
script
tags
<script src="file1.js"></script>
<script src="file2.js"></script>
<script src="file3.js"></script>
• All
is
loaded
to
global
namespace
• Some
scripts
depend
each
other
-‐>
order
is
important.
• Download
>me!
208. Defining
Modules
• Use
define
func>on
of
RequireJS
• Each
module
in
separate
file
(.js)
– File
name
will
be
a
module
ID.
• Modules
are
dependent
on
others
– Module
declares
a
list
of
other
modules
for
dependency
– No
more
includes
in
right
order,
modules
interact
with
each
other
without
global
namespace
• Module
is
defined
as
"factory"
– Can
be
object
or
func>on
that
returns
a
value
210. RequireJS:
How
to
Use?
1. Download
file
script
for
Browser
or
Command
line
– http://requirejs.org/docs/start.html#get
2. Add
RequireJS
to
your
web
page
(if
using
browser)
<script data-main="scripts/main" src="scripts/require.js">
</script>
3. Use
predefined
directory
structure
211. <!DOCTYPE html>
<html>
<head>
<title>Title</title>
<meta charset="UTF-8" />
<style media="screen"></style>
<!--
Define single entry-point to your app.
data-main attribute tells require.js to load
scripts/main.js after require.js loads.
js is appended by default main -> main.js
www/index.html
scripts/require.js
main.js
modules/module1.js
module2.js
-->
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
</body>
</html>
212. main.js
// Load modules and use them
// require() function has two arguments
// 1) array of dependencies
// 2) callback function to execute once all the dependencies have loaded.
// function arguments are the specified dependencies!
require(['modules/number', 'modules/counter', 'modules/album'], function(number, counter,
album){
// do something with the loaded modules
console.log(number)
console.log(album.title)
counter.increment();
counter.increment();
console.log(counter.getValue())
});
213. main.js
// Load modules and use them
// require() function has two arguments
// 1) array of dependencies
// 2) callback function to execute once all the dependencies have loaded.
// function arguments are the specified dependencies!
require(['modules/module1', 'modules/module2'], function(Module1, Module2){
// do something with the loaded modules
var module1 = new Module1();
var module2 = new Module2();
console.log(module1.getName())
console.log(module2.getName())
});
214. modules/module1+2.js
module1.js
define([], function () {
function returnedModule() {
var name = 'Module 1';
this.getName = function () {
return name;
}
};
return returnedModule;
});
module2.js
define(['modules/module1'], function (Module1) {
var module1 = new Module1()
function returnedModule() {
var name = 'Module 2: ';
this.getName = function () {
return name + module1.getName();
}
};
return returnedModule;
});
215. JQuery
and
RequireJS
• JQuery
is
AMD
compa>ble
• Download
jquery
–
file
and
name
it
as
"jquery.js"
• Amer
this
you
can
use
it
like
any
other
module!
216. JQuery
and
RequireJS
require(['jquery'], function(jquery){
// do something with the loaded modules
jquery( "#myform" ).submit(function( event ) {
...
event.preventDefault();
});
});
219. Designing
Libraries
• Designing
JS
libraries
are
hard
– Dynamic
nature
of
the
language
– Difficult
to
keep
things
truly
private
/
sandboxed
• Let’s
look
at
some
general
principals
about
designing
libraries
• When
possible,
see
how
exis>ng
libraries
have
done
things..
220. API
Design
• Consistent
– Easy
to
learn
when
each
module
have
a
similar
API
• Clean
• Well
documented
• Consider
plugin
architecture
222. Anonymous
Closures
• Create
anonymous
func>on
and
execute
it
immediately
(function () {
// ... all vars and functions are in this
// scope only
// still maintains access to all globals
}());
223. Defining
Modules
• Closures
provide
handy
way
of
keeping
module
code
sandboxed
– Less
pollu>on
to
global
namespace
– Avoid
modules
breaking
each
other
– Modules
can
access
globals
• In-‐depth
tutorial
– h?p://www.adequatelygood.com/2010/3/
JavaScript-‐Module-‐Pa?ern-‐In-‐Depth
224. Defining
Modules
var MODULE1 = function() {
// Place module implementation here.
// All vars and functions declared here are private to
// this scope.
// Can access globals if needed.
}();
225. var MODULE1 = function() {
// Private stuff (notice the single var pattern)
var privateVar1 = "",
privateVar2 = "moi",
privateFunc1 = function() { /* ... */ },
privateFunc2 = function() { /* ... */ };
function privateFunc3() { /* ... */ }
// Public stuff exported as part of an object. Due to the
// closure, the public functions can access all the private
// vars and functions as well.
return {
foo: function() { return "Hello World"; },
bar: function() { privateVar1 = "Hello!" },
publicVar1: "",
publicVar2: 12
}
}();
console.log(MODULE1.foo()); // “Hello World”
console.log(MODULE1.publicVar2); // 12
console.log(MODULE1.privateVar1); undefined
226. About
Globals
// - Code should not rely on certain global objects to
// be available...
// - Local variables are more efficient
// - Shorter lookup paths for objects
// - Can be minified to reduce file size
var MODULE2 = function(globalWindowObject, documentObject) {
var width = globalWindowObject.innerWidth;
return { prop: width };
}(this, this.document);
console.log(MODULE2.prop);
228. Test-‐driven
development
• Each
new
feature
begins
with
wri<ng
a
test!
– Test
will
fail
since
the
produc>on
code
does
not
exist
yet
• Write
the
code
• Run
automated
tests
to
see
if
if
test
cases
pass
• Automated
tests?
– We
need
a
framework…
229. JS
Unit
Tes>ng
Frameworks
• Lot
of
op>ons
– JSUnit,
YUI
Test,
QUnit,
Google
Closure
Tools
230. QUnit
• QUnit
is
a
JS
unit
tes>ng
framework
• Can
be
used
in
client
and
also
in
server
(Node.js)
• Was
originally
developed
as
part
of
JQuery
– Extracted
its
own
project
and
became
known
as
"QUnit"
• How?
– Download
qunit.js
and
qunit.css
– Write
a
simple
HTML
page
to
run
the
tests
– Write
the
tests
235. Brief
look
of
Op>mizing
• Script
deployment
• Code
op>miza>on
– Loops,
strings,
DOM
access
and
data
access
• Mul>threading
with
Web
Workers
• Performance
tools
236. Script
Deployment
• Group
to
have
as
few
files
as
possible!
– Loading
one
file
is
much
be?er
than
ten
files,
HTTP
overhead!
• Can
be
done
at
build
>me
or
at
run
>me
• Run
>me
grouping
– src=“h?p://site.com/combine?foo.js&bar.js”
237. Script
Deployment
• Minify
or
gzip
your
scripts
(for
example:
closure
compiler)
– Reduces
the
size
– Code
gets
obfuscated
– Some
older
browsers
do
not
support
gzipped
files
238. Code
Op>miza>on
• Do
not
op<mize
your
code!
– Unreadable
code
– Concentrate
on
maintainable
• If
you
have
to
op<mize
– Concentrate
code
that
executed
most
omen
• Check
string
and
DOM
opera<ons
– These
are
slow
in
JS!
239. Data
and
Property
Access
• Data
and
property
access
may
be
expensive
– document.getElementById(“a”).appendChild(child1);
– document.getElementById(“a”).appendChild(child2);
• Cache
frequently
used
objects
– var x = document.getElementById(“a”);
– x.appendChild(child1);
– x.appendChild(child2);
240. Strings
• Avoid
– mystring
+=
“first”
+
“second”
– Creates
temporary
string
in
memory
• Use
– mystring
+=
“first”;
– mystring
+=
“second”;
• Or
use
Array.join()
– myArray
=
[“first”,
“second”];
– var
str
=
myArray.join();
241. Loops
• Don’t
use
for-‐in
in
arrays,
requires
addi>onal
property
lookups
• Cache
variables!
var len = myarray.length;
var element =
document.getElementById(“id”);
for(var i = 0; i<len; i++) {
// Use element
}
242. Web
Workers
• Web
worker
is
a
JS
way
of
doing
things
in
background.
W3C
recommenda:on.
– “API
that
allows
Web
applica>on
authors
to
spawn
background
workers
running
scripts
in
parallel
to
their
main
page.”
– Web
worker
spec
is
separate
spec
from
HTML5
• Bring
mul>threading
to
your
app
– Heavy
calcula>ons
or
long-‐running
tasks
in
the
background
– Keep
UI
responsive
• No
need
to
use
Web
Workers
in
AJAX
(mul>-‐threading
on
by
default)
• Cannot
manipulate
UI
(DOM)!
243. <!DOCTYPE HTML>
<html>
<head>
<title>Big for loop</title>
<script>
function sayHello(){
var worker = new Worker('worker.js');
worker.onmessage = function (event) {
alert("Completed " + event.data + " iterations" );
};
worker.postMessage(50000);
}
</script>
</head>
<body>
<input type="button" onclick="sayHello();" value="Say Hello"/>
</body>
</html>
244. onmessage = function(event) {
var number = event.data;
for (var i = 0; i <= number; i += 1){
var j = i;
}
postMessage(j);
}