Javascript fundamentals from a PHP developers' point of view. Compares some of the principles of javascript with their php counterpart. Introduces a way to build simple robust modules in Javascript.
You can view the source of the slides (html+js) here: https://bitbucket.org/chrisramakers/talk-javascript-for-php-developers
2. WHO AM I?
@chrisramakers
Zend Certified PHP Engineer
Software Engineer @ Nucleus
Front- and backend development
Building RESTFUL API's
Integrating them with AngularJS
4. WHAT IS THIS TALK ABOUT?
I can hear you "I know Javascript! Booooring!"
I'm not a guru either but I have a lot of experience.
So I'm going to share some of it with you.
History
Javascript Bootcamp
Writing modules
What will the future bring?
6. JAVASCRIPT HISTORY
Interpreted scripting language
Object oriented but not Class based
Most popular language on Github
Developed at Netscape in 1995
Around the same time as PHP (1997)
First called LiveScript, then renamed Javascript
Standardised as ECMAScript (ECMA-262) in 1997
Other implementations
Serverside: Netscape Enterprise Server, Node.JS,
Databases: CouchDB, MongoDB, Riak, ...
Coffeescript
Adobe: ExtendScript, Actionscript,
7. IT'S EVEN A POWERPOINT REPLACEMENT!
These slides are built with reveal.js
Check it out: lab.hakim.se/reveal-js
8. WE KNEW JAVASCRIPT LIKE THIS
Note: This is a screenshot, not a real error!!! :D
11. BUT WE COULD DO STUFF LIKE THIS TOO
fnto tollll( {
ucin rloool)
wno.pnsl.oain ')
idwoe(eflcto, ';
}
wno.nod=tollll;
idwola
rloool
And feel like a real hacker :)
note: this no longer works
12. HOW WE KNOW JAVASCRIPT
A lot has changed, there are many high quality libraries and tools available.
But we are not going to talk about that ...
15. OPERATORS CONTINUED ...
concat
operator +
i -operator
n
concatenates 2 strings
determines if the left operant is a property of the right
operant
dlt
eee
removes a property from an object
tpo
yef
returns the data type of an object
i s a c o determines of the left operant is of the the right operant
ntnef
object type
And more like n wt i , ...
e, hs
Again most of these should look familiar.
20. 9 GLOBAL CONSTRUCTORS
Not the same as constructors in PHP
Srn(
tig)
Nme(
ubr)
Boen)
ola(
Ary)
ra(
Ojc(
bet)
Err)
ro(
Rgx(
eEp)
Dt(
ae)
Fnto(
ucin)
21. IMMUTABLE
All constructors are immutable Objects
Srn.rttp.ped=fnto(a)
tigpooyeapn
ucinvl{
ti =ti +vl
hs
hs
a;
}
vra='o'
a
Fo;
vrb=aapn(Br)
a
.ped'a';
ReferenceError: Invalid left-hand side in assignment
22. LITERALS AND CONSTRUCTORS
We don't need constructors ... we got literals!
Literal
String
Constructor
"ulu"
Nces
nwSrn(Nces)
e tig"ulu";
Boolean t u
re
nwBoentu)
e ola(re;
Array
[a,'';
'' a]
nwAry'' '';
e ra(a, b)
Objects
{a:''}
b
nwOjc(;
e bet)
Number 1 2 ;
.3
nwNme(.3;
e ubr12)
RegExp
nwRgx([-],'';
e eEp'AZ' i)
/AZ/;
[-]i
Function f n t o ( ) r t r x 1 } n w F n t o ( x , ' e u n x 1 ' ;
ucinx{ eun +; ; e ucin'' rtr +;)
Date
There is no Date literal
nwDt(03 1,2)
e ae21, 1 3;
23. RELATION BETWEEN LITERALS AND CONSTRUCTORS
vra="obr;
a
foa"
vrb=atUprae)
a
.opeCs(;
aetb;/ Aet "OBR
lr() / lrs FOA"
Constructors wrap literals internally
Javascript internally converts primitives to their object counterpart
Causes some really funky behaviour!
WTFPM++
24. AND NOW THE "FUN" BEGINS ...
TPO
YEF
tpo 'o' / "tig
yef fo; / srn"
tpo Srn; / "ucin
yef tig
/ fnto"
tpo Srn(; / "tig
yef tig)
/ srn"
vrs=nwSrn(fo)
a
e tig'o';
tpo s / "bet
yef
/ ojc"
25. ISACO
NTNEF
vrfo=nwSrn(fo)
a o
e tig'o';
vrbr='a'
a a
br;
foisaco Srn;/ tu
o ntnef tig / re
brisaco Srn;/ fle
a ntnef tig / as
Wait ... it gets better :)
vrby =nwAry'o' 'o';
a os
e ra(Je, Bb)
vrgrs=[Jn' 'lc';
a il
'ae, Aie]
by isaco Ary / tu
os ntnef ra; / re
grsisaco Ary / tu
il ntnef ra; / re
i s a c o on navite data types is not reliable!
ntnef
use j u r . y e )a g l r i S r n ( , ...
Qeytp(, nua.stig)
26. ERRORS AND ERROR HANDLING
PHP
Javascript
ty{..}cthe {..}
r
.
ac()
.
ty{..}cthe {..}
r
.
ac()
.
trwnwEcpinmg cd)
ho e xeto(s, oe;
trw'oehn wn wog'
ho Smtig et rn!;
trw50
ho 0;
trw'p;
ho u'
trw{esg:'o' cd:50;
ho msae fo, oe 0}
trwnwErr'p)
ho e ro(u';
27. SCOPE
Scope refers to where a variable or functions are accessible
and in what context they are being manipulated.
There 2 types of scope
Global
Local
28. GLOBAL SCOPE
When something is in the global scope
it means that it is accessible from anywhere in your code.
Basically it means it's attached to the window object which is the topmost
object.
vrfo="ulu"
a o
Nces;
fnto br)
ucin a({
aetfo;
lr(o)
}
br) / aet 'ulu'
a(; / lrs Nces
aetfo / as aet 'ulu'
lr(o) / lo lrs Nces
aetwno.o)/ aanaet 'ulu'
lr(idwfo / gi lrs Nces
29. LOCAL SCOPE
When something is in the local scope it means it's only available in the
containing function and all functions defined at the same level or deeper.
fnto br)
ucin a({
vrfo="ulu"
a o
Nces;
aetfo;
lr(o)
}
br) / aet 'ulu'
a(; / lrs Nces
aetfo / err foi ntdfnd
lr(o) / ro: o s o eie
aetwno.o)/ err foi ntdfnd
lr(idwfo / ro: o s o eie
30. CLOSURES
A closure is an expression (typically a function) that can have
variables together with an environment that binds those variables
(that "closes" the expression).
31. PHP CLOSURES
In PHP closures are most commonly called 'anonymous functions' and are
implemented using the Closure class.
/ PPCoue
/ H lsr
$o =fnto( {
fo
ucin)
rtr 'ulu'
eun Nces;
}
;
eh $o(;/ otus'ulu'
co fo) / upt Nces
eh gtcas$o) / otus'lsr'
co e_ls(fo; / upt Coue
32. PHP CLOSURES AND SCOPE
$o ='ulu'
fo
Nces;
$a =fnto( {
br
ucin)
rtr $o;
eun fo
}
;
eh $a(;/ PPNtc:Udfndvral $o
co br) / H oie neie aibe fo
We need the 'use' construct.
$o ='ulu'
fo
Nces;
$a =fnto( ue(fo {/ add's'cntut
br
ucin) s $o)
/ de ue osrc
rtr $o;
eun fo
}
;
eh $o(;/ Otus'ulu'
co fo) / upt Nces
33. JAVASCRIPT CLOSURES
Whenever you see a function, wrapped within another function, a closure is
created and the inner function has access to all variables defined in the outer
function.
34. JAVASCRIPT CLOSURES
/ otrfnto
/ ue ucin
fnto getwo {
ucin re(h)
vrpei ='ecm a '
a rfx
Wloe t ;
/ Inrfnto
/ ne ucin
fnto otu(ufx {
ucin uptsfi)
aetpei +wo+sfi)
lr(rfx
h
ufx;
}
;
otu(!)
upt'';
}
get'ulu';/ Aet 'ecm a Nces'
re(Nces) / lrs Wloe t ulu!
Outside the g e t )
r e ( function, there is no way to access the p e i
rfx
variable.
Only functions defined within the g e t )
r e ( function have access to this
variable, same goes for the w o
h argument which is also contained within the
closure.
35. CLOSURES IN JAVASCRIPT
Now we can modify the code to return the inner function.
fnto getwo {
ucin re(h)
vrpei ='el '
a rfx
Hlo ;
vrf=fnto(ufx {
a
ucinsfi)
aetpei +wo+sfi)
lr(rfx
h
ufx;
}
;
rtr f
eun ;
}
vrjeree =get'o';
a oGetr
re(je)
jeree(?) / Aet 'el je'
oGetr''; / lrs Hlo o?
jeree.rfx / udfnd
oGetrpei; / neie
This way we receive an executable function from the g e t )
r e ( call,
but we still have no way to modify the value of p e i .
rfx
Looks a lot like private variables in PHP
36. CLOSURES IN JAVASCRIPT
Lets add an accessor and mutator (getter and setter).
fnto getwo {
ucin re(h)
vrpei ='el '
a rfx
Hlo ;
vrf=fnto(ufx {
a
ucinsfi)
aetpei +wo+sfi)
lr(rfx
h
ufx;
}
;
fstrfx=fnto() pei =p }
.ePei
ucinp{ rfx
;
fgtrfx=fnto({rtr pei;}
.ePei
ucin) eun rfx
rtr f
eun ;
}
vrjeree =get'o';
a oGetr
re(je)
jeree(?) / Aet 'el je'
oGetr''; / lrs Hlo o?
jeree.ePei(Hy';/ jei da ..
oGetrstrfx'e ) / o s ef .
jeree(!!) / Aet 'e je!'
oGetr'!'; / lrs Hy o!!
37. SELF EXECUTING FUNCTION PATTERN
(ucin){
fnto(
/ ..
/ .
});
()
Also called I F or Immediately Invoked Function Expression
IE
Creates it's own isolated scope without polluting the global scope.
Allows us to 'import' variables into the closure without addressing them
globally
(ucin$ Y {
fnto(, )
/ ..
/ .
}jur,YHO)
(Qey AO);
38. WRITING JAVASCRIPT MODULES
Lets do something usefull with it now ...
Javascript doesn't know the concept c a s s
l s e (yet)
Nor does it have private/public access to properties
How do we build a robust module in javascript then?
41. vrCUTR=(ucin)
a ONE
fnto({
vr_one =0
a cutr
;
vrpbi ={;
a ulc
}
rtr pbi;
eun ulc
});
()
BUILDING A MODULE
Now we have to actually return
something from our self-executing
function so C U T R not
O N E is
udfnd
neie
cnoelgCUTR;
osl.o(ONE)
/ Ojc {
/ bet }
42. vrCUTR=(ucin)
a ONE
fnto({
vr_one =0
a cutr
;
vrpbi ={
a ulc
iceet:fnto({
nrmn
ucin)
_one+;
cutr+
}
,
gtau :fnto({
eVle
ucin)
rtr _one;
eun cutr
}
}
;
rtr pbi;
eun ulc
});
()
BUILDING A MODULE
If we now add some functions to
p b i , we create a closure inside
ulc
the self-executing function.
cnoelgCUTRgVle);/ 0
osl.o(ONE.eau() /
CUTRiceet)
ONE.nrmn(;
cnoelgCUTRgVle);/ 1
osl.o(ONE.eau() /
cnoelgCUTR_one) / udfnd
osl.o(ONE.cutr; / neie
43. vrCUTR=(ucin)
a ONE
fnto({
vr_one =0
a cutr
;
vrfra =fnto(au)
a omt
ucinvle{
rtr 'one i '+vle
eun Cutr s
au;
}
vrpbi ={
a ulc
iceet:fnto({
nrmn
ucin)
_one+;
cutr+
}
,
gtau :fnto({
eVle
ucin)
rtr fra(cutr;
eun omt_one)
}
}
;
rtr pbi;
eun ulc
});
()
BUILDING A MODULE
Now lets add a "private" method to
format the output a little
CUTRiceet)
ONE.nrmn(;
CUTRiceet)
ONE.nrmn(;
cnoelgCUTRgVle);
osl.o(ONE.eau()
/ Cutri 2
/ one s
44. vrCUTR=(ucin)
a ONE
fnto({
vr_one =0
a cutr
;
vr_omt='one i '
a fra
Cutr s ;
vrfra =fnto(au)
a omt
ucinvle{
rtr _omt+vle
eun fra
au;
}
vrpbi ={
a ulc
iceet:fnto({
nrmn
ucin)
_one+;
cutr+
}
,
gtau :fnto({
eVle
ucin)
rtr fra(cutr;
eun omt_one)
}
,
stomt fnto(t)
eFra: ucinsr{
_omt=sr
fra
t;
}
}
;
rtr pbi;
eun ulc
});
()
BUILDING A MODULE
But we also want to change the
output format of the module. Lets add
a "private" property and a "setter".
CUTRiceet)
ONE.nrmn(;
CUTRiceet)
ONE.nrmn(;
cnoelgCUTRgVle);
osl.o(ONE.eau()
/ Cutri 2
/ one s
CUTRstomt'au =';
ONE.eFra(Vle
)
cnoelgCUTRgVle);
osl.o(ONE.eau()
/ Vle=2
/ au
CUTR_omt="obr
ONE.fra
Foa"
cnoelgCUTRgVle);
osl.o(ONE.eau()
/ Vle=2
/ au
45. vrCUTR=(ucin)
a ONE
fnto({
vr_otie,_one =0
a cnanr cutr
,
_omt='one i '
fra
Cutr s ;
vrfra =fnto(au)
a omt
ucinvle{
rtr _omt+vle
eun fra
au;
}
vrpbi ={
a ulc
/ si..
/ np.
}
;
vrii =fnto(otie)
a nt
ucincnanr{
_otie =cnanr
cnanr
otie;
_otie.neHM =
cnanrinrTL
'one ray'
Cutr ed!;
rtr pbi;
eun ulc
}
rtr ii;
eun nt
});
()
BUILDING A MODULE
Now we want to configure the
module from the outside. The easiest
way to that is to add an i i
nt
function.
DEMO TIME ...
46. <i i=cnanr>/i>
dv d"otie"<dv
<utni=tigr>d 1/utn
bto d"rge"Ad <bto>
vrc=dcmn.eEeetyd'otie'
a
ouetgtlmnBI(cnanr)
t=dcmn.eEeetyd'rge';
ouetgtlmnBI(tigr)
vrmCutr=CUTRc;
a yone
ONE()
tocik=fnto({
.nlc
ucin)
mCutriceet)
yone.nrmn(;
}
;
Counter ready!
Add 1
Try it yourself at http://ncl.uz/counterdemo
47. A LITTLE EXTRA ...
What if we need to build a really large module?
Spread over several files?
MODULE AUGMENTATION
48. / mdl.s
/ ouej
vrCUTR=(ucin)
a ONE
fnto({
vr_one =0
a cutr
;
vr_omt='one :'
a fra
Cutr
;
vrfra =fnto(au)
a omt
ucinvle{
rtr _omt+vle
eun fra
au;
}
vrpbi ={
a ulc
iceet:fnto({
nrmn
ucin)
_one+;
cutr+
}
,
gtau :fnto({
eVle
ucin)
rtr fra(cutr;
eun omt_one)
}
,
stomt fnto(t)
eFra: ucinsr{
_omt=sr
fra
t;
}
}
;
rtr pbi;
eun ulc
});
()
AUGMENTING A MODULE
We want to add a new public method
s o t the already existing
h u to
CUTR
ONE
/ mdl.hu.s
/ ouesotj
vrCUTR=(ucinpbi)
a ONE
fnto(ulc{
pbi.hu =fnto({
ulcsot
ucin)
vrotu =pbi.eVle)
a upt
ulcgtau(;
rtr otu.opeCs(;
eun upttUprae)
}
;
rtr pbi;
eun ulc
}CUTR)
(ONE);
Can only access/override the public
API
49. THE BAD PARTS ...
Only one instance
No inheritance system
Augmentation only has access to the public API
50. THE FUTURE
UMD (UNIVERSAL MODULE DEFINITION)
Defines a way to structure modules so they work
both in the browser and on the server
github.com/umdjs/umd
AMD (ASYNCHRONOUS MODULE DEFINITION)
Defines a way to load modules in any arbitrary order
github.com/amdjs/amdjs-api
51. TAKING A LOOK AT ECMASCRIPT 6
WHAT CAN WE EXPECT FROM ES6?
Current status: kangax.github.io/es5-compat-table/es6
52. DEFAULT PARAMETERS
ES5
fnto iceetx y {
ucin nrmn(, )
y=y| 1
| ;
rtr x+ y
eun
= ;
}
ES6
fnto iceetx y=1 {
ucin nrmn(,
)
rtr x+ y
eun
= ;
}
53. LEXICAL SCOPE WITH L T
E
ES5
fnto dSmtig){
ucin ooehn(
vrx=5
a
;
i (oeodto){
f smCniin
vrx=1;
a
0
dSmtiglex;
ooehnEs()
}
cnoelgx;/ 1 !
osl.o() / 0 !
}
ES6
fnto dSmtig){
ucin ooehn(
ltx=5
e
;
i (oeodto){
f smCniin
ltx=1;
e
0
dSmtiglex;
ooehnEs()
}
cnoelgx;/ 5!
osl.o() /
!
}
54. CONSTANTS
ES5
/ Np ..n cntnsfryu
/ oe . o osat o o
ES6
cntlmt=10
os ii
0;
lmt=20 / SnaErr
ii
0; / ytxro
58. WRAPPING UP ...
You can build pretty robust modules in Javascript
But they are still not comparable to PHP Classes
We haven't touched inheritance, interfaces, abstract classes, etc ...
These are all possible with Javascript
... but that's for another time