►
From YouTube: JavaScript the Grumpy Parts - Rob Richardson, @rob_rich
Description
We love JavaScript, but we must admit: it's weird. Why does `this` behave as it does? How does variable scope work? Why do we have such comical behavior when comparing mixed types? Let's pull back the covers of these scenarios, and learn how it truly works. You may find a new reason to fall in love with JavaScript.
A
A
Here's
the
part
where
I
tell
you,
I'm
definitely
going
to
post
the
slides
on
my
site
tonight
and
well
they're.
Already
there
I've
been
the
person
chasing
the
the
st
speaker
as
well
and
yeah.
Here's
javascript
grumpy
parts.
The
slides
are
online
right
now,
while
you're
here
on
robrich.org
click
on
about
me
and
you'll,
get
to
this
spot.
That
talks
a
little
bit
about
the
things
that
I
do.
A
I'm
a
microsoft
mvp,
a
friend
of
redgate,
a
cyril
developer,
evangelist
and
let
me
tell
you
about
azgiv
camp
azgive
camp
brings
volunteer
developers
together
with
charities
to
build
free
software.
We
start
friday
after
work
sunday
afternoon.
We
deliver
that
completed
software
to
the
charities.
Sleep
is
optional.
Caffeine
provided,
if
you're
in
phoenix,
come
join
us
for
the
next
a-z
gift
camp
or,
if
you'd,
like
a
gift
camp,
where
you're
connecting
from
hit
me
up
on
email
or
on
twitter
and
let's
get
a
gift
camp
in
your
neighborhood
too.
A
A
Now
we
will
need
to
go
a
little
fast
because
well,
we
only
have
a
half
hour
together,
but
I
would
like
to
thank
john
mills.
He
has
a
talk,
a
job,
a
guide
to
javascript's
gary
side
that
helped
inspire
this
talk.
Now
he
goes
into
different
directions,
but
his
talk
is
amazing,
and
so,
if
you
have
a
chance,
listen
to
him
as
well,
we'll
probably
hit
the
end
of
my
knowledge
and
that'll
be
really
fun.
A
I
look
forward
to
the
part
where
I
say
I
don't
know
in
the
beginning,
brendan
ike
created
javascript
in
10
days
25
years
ago.
I've
written
some
code
25
years
ago
and
it
was
pretty
awful,
and
yet
here
we
all
are
talking
about.
Javascript
brendan
did
an
amazing
job.
If
you'd
like
to
learn
more
about
brendan,
read
more
or
watch
more
to
see
how
he
invented
javascript,
it's
really
cool.
Each
of
these
blue
links
in
the
slides
here
from
rawritch.org
are
links
to
be
able
to
dial
into
additional
information.
A
Now,
what's
really
cool
is
we
now
have
a
bunch
of
javascript
engines
that
are,
for
the
most
part,
really
high
fidelity
in
v8?
We
have
chrome
in
spider
monkey,
we
have
firefox
in
in
internet
explorer,
we
have
chakra
in
safari,
we
have
javascript
core,
and
each
of
these
javascript
engines
works
pretty
much.
The
same
brendan
ike's
library
was
cloned
with
amazing
fidelity.
Now
we
talk
about
differences
between
javascript
in
different
browsers.
A
Html5
has
made
that
a
little
bit
less
of
a
concern,
but
that
was
about
our
interaction
with
the
document
object
model,
the
dom
the
javascript
runtime
itself
is
amazingly
compatible,
including
all
the
bugs,
so
javascript
was
copied
with
incredible
precision,
including
the
bugs.
Let's
take
a
look
at
some
of
the
weird
things
now.
Some
of
the
major
design
goals
of
this
language
was.
It
was
a
language
that
well
runs
over
there.
When
we
develop
javascript,
we
ship
our
source
code,
a
js
file.
A
A
Now,
if
it
keeps
running
it's
going
to
try
to
be
as
forgiving
as
possible,
so
well,
if
it
notices
a
syntax
error,
it'll
back
up
and
see
if
it
can
put
a
semicolon
in
to
be
able
to
solve
that
now
are
semicolons
required
in
javascript.
Well,
yes,
they
are,
but
the
engine
may
insert
them
automatically.
So
if
you
see
javascript
without
semicolons,
that's
why
we're
leveraging
that
piece
of
the
compiler
that
says
hey.
Let
me
fix
that
for
you.
A
So
let's
take
a
look
at
some
of
the
weird
things
in
javascript.
This
is
the
javascript
watt
talk
and
I'm
not
going
to
play
it
for
you,
but
I
invite
you
to
grab
these
slides
from
robrich.org
and
click
play.
What's
particularly
cool
is
this
is
brendan
ike
playing
the
javascript
wet
talk
at
one
of
his
talks
and
his
commentary
throughout
it.
It
is
amazing,
so,
let's
take
a
look
at
some
weird
things:
undefined
well,
undefined
is
just
a
variable.
A
So
what
if
we
define
it
in
more
recent
versions
of
javascript
of
ecmascript,
it
is
defined
as
a
constant,
so
we
can't
override
it,
but
this
led
to
some
really
really
interesting.
Bugs
if
so,
for
example,
we
defined
javascript
type
of
null
type
of
null
is
an
object,
should
it
be
null,
should
it
be
an
object?
A
This
is
probably
one
of
those
bugs
brenda
knight
created
it
in
10
days
and
a
few
weeks
after
that
he
said,
you
know,
there's
some
bugs
here,
I'd
like
to
come
back
and
fix
and
he
was
told,
hey,
there's
40
developers
already
building
with
javascript
right
now.
We
need
to
not
change
it.
That
would
be
backwards,
incompatible,
40
developers.
I
bet
there's
40
developers
in
this
room
that
wish
we
had
gone
back
and
fixed
it,
but
he
made
the
best
decision
that
he
could
at
the
time
here's
another
one
type
of
nan.
A
A
Now
I
grant
that
in
modern
javascript
engines
we
have
mechanisms
for
code
split
tree
shaking
and
just-in-time
compilation,
and
those
are
amazing,
but
at
its
core
javascript
is
a
two-phase
compiler.
The
first
phase
goes
and
looks
for
variable
declarations,
and
it
kind
of
sets
aside
that
memory
for
those
variables.
The
next
phase
is
to
run
the
code.
A
A
Let's
think
like
the
compiler
and
see
if
we
can
figure
it
out
now,
the
first
phase
we
go
look
for
variable
declarations:
here's
one
var
foo
equals
bar
okay,
so
we're
not
setting
it
to
bar.
Yet
that
would
be
the
execution
phase,
but
we
are
declaring
this
variable
varfu
next
phase.
Let's
go
execute
the
code,
so
we
start
out
declaring
this
function
then
we'll
call
it
so
we'll
start
off
and
we'll
console
log
foo.
Well,
we
already
have
this
foo
variable
declared.
A
We
haven't
set
its
value
yet
so
we
get
undefined.
If
true
now
variables
in
javascript
by
default
are
function
scoped,
not
curly,
brace
scoped.
So
we
know
that
this
foo
variable
exists
out
here
now
we're
going
to
set
it
to
bar
and
then
we'll
leave
the
curly
braces.
This
variable
continues
on
and
we
console
log
bar,
so
we
get
undefined
and
bar.
A
A
Now
that
variable
hoisting
is
a
cool
lie
that
we
tell
ourselves,
but
that's
not
actually
how
it
works.
How
it
works.
Is
this
two
phase?
Compiler,
yes,
variable,
hoisting,
it's
a
lie.
It's
a
convenient
lie
and
it
helps
us
to
think
about
this
in
kind
of
a
more
synchronous
way
without
having
to
separate
that
two-phase
compiler
mechanism.
A
Now
that's
interesting,
but
well
it
is
a
lie.
It's
a
very
convenient
lie
and
I
like
it,
but
hoisting
is
a
lie
so,
as
we
think
like
the
compiler,
we
can
see
how
that
variable
hoisting.
It
isn't
actually
moved.
Rather
it's
well,
it's
a
two-phase
compiler.
So
we
saw
this
code
and
we
saw
how
we
could
execute
it
in
interesting
ways.
Let's
take
a
look
at
defining
and
not
defining
variables
in
various
scopes.
A
Now
we
had
a
mechanism
before
where
we
declared
some
foo
variables.
Let's
declare
this
foo
variable
and
this
foo
variable
take
a
minute
to
pause
the
video
and
think
through
this.
What
will
it
do
now?
Let's
think
like
the
compiler
and
figure
it
out.
First
phase:
we
go
look
for
variable
declarations.
We
find
this
one
foo.
So,
let's
declare
that
one
we
find
this
one.
Let's
declare
that
one
now
variables
are
declared
with
function
scope,
so
we
have
two
different
foo
variables
in
different
scopes:
an
inner
foo
and
an
outer
foo.
A
A
We
leave
the
curly,
brace
scope,
functions,
our
functions
to
find
the
scope,
and
so
now
we
cancel
log
foo
and
we
get
this
bam
again.
We
leave
our
function
and
now
we
need
to
find
this
outer
variable.
Is
there
a
variable
defined
in
this
scope?
Yes,
there
is
right
here,
so
we'll
output,
bam,
bam
and
bar.
A
Let's
change
this
up
a
little
bit
instead
of
declaring
the
variable
here.
Let's
declare
it
here.
Stop
the
video
here.
How
does
this
work?
Let's
think
like
the
compiler
and
figure
it
out?
Our
first
phase
is
to
define
all
of
the
variables
define
this
one
to
find
that
one,
and
the
second
phase
is
to
execute
this
so
we'll
set
our
outer
food
to
bar,
we'll
call
our
function
set
our
inner
food
to
baths
wait
a
minute.
A
Where
do
we
get
this
in
our
food?
Well,
we
go
looking
for
variables
in
the
current
scope.
Here's
one
this
variable
is
defined
as
a
function
based
variable,
so
we'll
set
it
to
baz,
then
we'll
set
it
to
bam,
we'll
console
log
bam,
we'll
cancel
log
bam
again
and
as
we
leave
the
function,
then
we
console
log
bar
bam.
Bam
bar!
Is
that
what
you
got?
A
Let's
do
it
again,
but
instead
we
won't
declare
these
variables
at
all.
Okay,
first
step:
let's
go
look
for
variables
to
declare
here's
a
variable.
Let's
declare
that
one
second
phase,
let's
go,
execute
it
okay,
so
let's
set
this
variable
to
bar:
let's
call
our
function.
Now
we
go
looking
for
a
food
variable.
A
Is
there
a
food
variable
in
the
current
scope?
There
isn't
so
we
walk
up
scopes.
Javascript
is
trying
to
help
us.
Of
course
the
code
is
running
over
there
once
the
user
once
the
developer
has
left.
So
we
go
looking
up
scopes.
Oh
here's,
a
foo
variable,
let's
use
this
one
so
where
it
was
bar,
it
is
now
baz.
A
A
Now,
let's
think
like
the
compiler
and
figure
it
out
first
phase:
let's
go
define
all
of
our
variables.
There
aren't
any
second
phase:
let's
go
execute
so
foo
equals
bar.
Is
there
a
food
variable
in
the
scope?
There
isn't?
Let's
climb
up
the
scope.
Well,
in
this
case,
we'll
climb
all
the
way
up
to
the
global
scope,
and
we
will
define
a
variable
there.
Javascript
is
trying
to
help
us
succeed,
and
so
we
define
a
global
variable
foo
and
set
its
value
to
bar.
A
A
Let's
go
find
that
variable
again
set
it
to
bam,
bam
bam.
We
leave
here
and
we
log
bam
again.
Now.
That's
interesting
javascript
helped
us
by
declaring
a
global
variable,
but
well
what
if
that
variable
was
called
I
and
what?
If
you
used
it,
and
I
used
it
now,
we
may
overwrite
each
other.
It
is,
after
all,
a
global
variable.
Javascript
tried
to
help
our
code
succeed,
but
it
may
have
done
us
a
disservice
by
just
automatically
creating
a
variable.
A
Let's
do
this
again,
but
now,
let's
set
foo
to
bam,
pause.
The
video
here
see
what
happens
now,
let's
think
like
the
compiler
and
figure
it
out
first
step.
Let's
define
this
foo
variable
second
step:
let's
execute
we'll
set
foo
to
bar
we'll
call
our
function
foo.
Is
there
a
foo
defined
in
this
scope?
There
is
not
okay,
here's
a
foo!
So
let's
set
it
from
bar
to
baz.
A
A
A
So,
let's
do
it
again
now
we've
defined
variables
here
with
var,
but
let's
switch
it
up
to
let
now
let
is
new
in
es6
or
es2015
and
let
is
defined
as
bound
to
curly
braces
instead
of
bound
to
function.
Scope,
pause,
pause,
the
video
here
and
see
what
happens
now,
let's
think
like
the
compiler
and
figure
it
out.
First,
we
need
to
go
define
all
of
our
variables.
Here's
one
and
here's
one.
Next,
let's
execute:
let's
set
the
outer
food
to
bar,
then
let's
call
our
function
now
we're
looking
for
a
foo
variable.
A
Is
there
a
food
variable
defined
in
this
scope?
No,
this!
Let
means
that
this
variable
is
defined
to
an
inner
scope.
So
we
go
looking
for
another
foo
variable
in
an
outer
scope.
Oh
there's
one
right
here,
so
we'll
change
it
from
bar
to
baz,
then
inside
of
our,
if
block,
let's
create
a
new
variable
and
we'll
set
that
to
bam.
So,
let's
console
log
bam
inside
here.
Then,
let's
console.log,
this
variable,
we
don't
have
one
defined
in
this
scope,
but
we
have
one
defined
in
the
outer
scope.
A
Okay,
let's
think
like
the
compiler
and
see
if
we
can
figure
it
out.
First,
we
declare
our
all
our
variables
there's
just
one
right
here.
Second,
we'll
execute
we'll
call
our
function,
we'll
go
looking
for
a
variable.
There
isn't
one
in
this
scope.
There
isn't
one
in
the
outer
scope,
so
we
define
a
new
global
variable,
called
foo
and
set
its
value
to
baz
inside
this.
If
block,
we
have
this
curly
brace
scoped
variable,
so
we
output,
bam
and
then
baz
and
then
out
here
we
go
looking
for
a
variable
in
the
current
scope.
A
A
Let's
do
it
again,
but
let's
define
these
two
variables
here.
What
happens
in
this
case?
Let's
think
like
the
compiler,
well,
everything
works
well
inside
this
function.
Once
we
get
out
here,
we're
going
to
get
to
this
foo
variable
and
we're
going
to
go,
look
for
a
global
foo
variable!
Well,
there's
no
variable
defined
in
this
scope.
Let's
keep
looking
for
a
global
variable.
Nothing
was
defined
here
because
all
these
variables
were
defined
so
we
get
a
reference
area.
Foo
is
not
defined.
A
A
A
Now,
if
we're
using
babel
to
transpile
from
es6
to
es5,
where
const
doesn't
exist,
then
it
changes
this
const
to
a
let
or
no
it
changes
a
const
to
a
var
and
yes,
we
can
assign
a
var
so
we'll
get
different
behavior
every
evergreen
browser
supports
es6
or
better.
Now,
so
probably
we
want
to
turn
down
babel
to
output,
es6
or
better
and
ensure
that
that
const
is
indeed
const,
but
that's
why
you
might
get
different
behavior
inside
of
babel,
so
we
took
a
look
at
defining
variables.
Let's
take
a
look
at
this.
A
A
A
A
So,
let's
create
a
new
mechanism
where
we
can
go
grab
a
button.
Now
we
grab
it
by
id
and
then
we
click
the
button
to
call
the
speak
function
now.
What's
the
thing
to
the
left
of
the
dot?
Well,
it's
the
button
so
when
I
say
this
dot
id
knowing
that
I
have
a
get
element
by
id,
I'm
going
to
output
the
button
perfect.
A
Now
what
if
we
want
to
change
the
speak
function
to
output,
the
name
in
100
milliseconds,
instead?
Okay,
so
let's
do
it
now,
when
we
call
obj1.speak
set
timeout,
is
going
to
create
a
whole
new
stack.
So
what
is
this
in
this
new
stack?
Well,
it's
the
global
function,
so
we're
going
to
get
ninja
twice,
let's
see
if
we
can
fix
that,
we
can
alter
what
this
means
by
calling
dot
call
now
we'll
say,
dot,
call
and
we'll
pass
in
what
we
want
this
to
be
so.
A
A
Now,
it's
going
to
say,
dot
call,
but
this
executes
it
right
away.
So
we
will
get
the
right
answer
ninja
and
doctor,
but
we
didn't
wait.
The
necessary
100
milliseconds,
let's
look
at
bind
now
bind,
is
a
great
way
to
create
a
closure,
a
new
function
that
has
this
set
the
way
we
expect.
We
can
kind
of
think
of
it
like
this.
This
isn't
the
correct
syntax,
but
we
can
think
of
it.
A
A
A
Now,
we'll
probably
see
in
our
code
object2.speak.bind
obj2
a
lot.
What
it's
trying
to
do
is
saying
I
want
to
set
this.
I
don't
want
any
ambiguity,
that's
perfect!
If
you
find
that
in
your
code,
that's
exactly
what
it's
doing
now,
let's
come
back
to
our
set
timeout
function
and
let's
call
dot,
bind
this
now
that
bind.
This
will
return
a
new
function
that
we
can
call
later
say
in
100
milliseconds.
A
A
A
Now
because
it
binds
at
the
point
where
it's
created
then
well.
This
is
bound
to
the
global
scope.
At
the
point
where
it's
created,
we
get
ninja
ninja,
ninja
oops
that
isn't
what
we
expected.
Okay,
so
let's
say
obj2.speak.bindobj2:
we
have
this
trick
that
allows
us
to
bind
this
well
kind
of.
This
is
already
bound
into
place,
so
wrapping
it
in
another
function
that
binds
it
to
something
else.
Then,
when
it
calls
this
inner
function,
it's
already
bound,
so
we
can't
re-bind
it
so
yeah
nope
that
didn't
work.
A
Okay,
so
here
in
our
function,
let's
use
an
arrow
function
here
we
know
that
it
binds
at
the
point
where
it's
created.
So
let's
use
that
to
grab
this
and
now
yes
ninja
doctor,
it
works
as
expected,
perfect.
Now
what
if
we
changed,
speak
to
be
an
arrow
function?
Well,
then,
it
wouldn't
behave
as
expected.
Now
it
would
bind
to
the
global
this,
but
because
we
have
this
outer
one
as
function
and
this
inner
one
is
an
arrow
function.
It
behaves
as
expected.
A
Now
that's
a
little
weird,
knowing
that
arrow
functions
bind
at
the
point
where
they're
created
will
help
us
to
understand
a
little
bit
about
how
it
works.
We
shouldn't
just
change
every
function
to
be
an
arrow
function
that
would
be
well
to
bind
this
too
much
and
we've
seen
that
we
can't
override
it
now.
Let's
briefly,
take
a
look
at
the
event
loop.
A
A
A
Now
we
start
out
with
that
set
timeout.
Okay.
Now
it's
counting
for
I
equals
one
to
three
and
it's
counting
and
it's
setting
new
content
up
here
to
finish
once
that
finishes,
it
comes
back
down
here
into
the
callback
queue
that,
as
the
call
stack
empties,
it
goes
and
grabs
the
next
thing
from
the
callback
queue
and
sets
it
in
place.
A
Now
this
highlights
that
great
scenario
where
what
is
it
outputting?
Well,
it's
outputting
the
current
I,
what
is
the
I
by
the
time
it
gets
here?
Well,
it's
three!
So
we're
gonna
console
log
three
three
times,
but
we
get
a
sense
for
the
call
stack
the
callback
queue
web
apis.
It
is
a
perfect
mechanism
for
being
able
to
visualize
those
three
pieces.
A
So
we've
got
that
stack
where,
as
the
content
is
run,
it's
going
to
run
through
all
of
the
pieces
in
the
stack,
it's
not
going
to
look
at
anything
in
the
callback
queue
until
the
stack
is
empty.
Once
the
stack
is
empty,
it
will
grab
the
next
piece
from
the
callback
queue
and
set
it
on
the
stack
and
process.
It
read
more
or
watch
more
about
this
and
learn
some
more
about
it.
A
Now,
as
we
look
at
node,
we
can
think
of
it
like
this.
Now
this
isn't
the
physical
layout,
but
this
is
a
good
logical
layout.
Each
request
has
its
own
stack
and
callback
queue
and
the
things
that
it's
waiting
for
now
as
as
node
goes
through.
It
looks
at
each
request
and
gets
it
a
little
bit
farther
well
what
if
this
request
is
going
to
count
from
one
to
a
billion?
A
So
we
might
see
something
like
this
set
timeout
zero.
Why
would
I
wait
zero
seconds?
Well
because
we're
trying
to
yield
the
threads
so
that
the
rest
of
the
quests
can
get
caught
up?
We
might
also
do
this
process.next
tick
and
in
more
modern
versions
of
node.
We
don't
even
need
the
empty
function
here.
We
can
just
say,
await
process
dot,
next
tick
and
now
we've
yielded
the
thread
for
a
second
and
let
everybody
else
catch
up.
That
is
perfect.
A
A
A
Well,
the
cool
part
is
that
async
and
await
has
this
mechanism
where
we
can
just
await
things
and
start
to
feel
as
if
it
was
synchronous?
That's
amazing!
Now,
because
it
feels
synchronous,
we
can
start
to
think
about
it
with.
You
know,
standard
fallback
mechanisms,
but
we
know
it'll
stop
here
until
this
is
done
and
it'll
stop
here
until
this
is
done
and
it's
not
blocking
the
thread,
it's
yielding
the
thread
for
other
things
and
then,
when
it
comes
back,
then
it'll
be
able
to
continue
on.
A
We
can
think
a
lot
more
synchronously,
in
spite
of
the
fact
that
it's
actually
executing
asynchronously,
that's
amazing!
Now
do
we
have
to
wait
until
we
do
a
big
bang
refactor
to
get
everything
nope
async
and
await
works
as
promises
under
the
hood.
So
we
have
this
async
function
and
let's
call
it
but
not
await
it.
A
A
A
Now
we
want
to
call
lib1
column,
two
notice,
how
we're
not
awaiting
them.
So
we
have
three
promises.
Well,
how
do
we
await
a
bunch
of
promises?
We
have
this
promise.all
and
we
can
await
that
and
then
we
have
all
our
results.
All
these
things
happen
simultaneously.
Well.
Kind
of
javascript
is
still
single
threaded,
but
I
didn't
have
to
wait
for
one
to
finish
before
I
started
too.