0 ratings0% found this document useful (0 votes) 10K views96 pagesJavaScript Cheatsheet
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here.
Available Formats
Download as PDF or read online on Scribd
se hal
AS Hla
had bY
RY
Zero To Mastery
AST =
Interpreter
Profiler ...< aI
bry aereoye
Compiler
t = -Y Optimized code
Nifty Snippet: 2008 was a pivotal moment for JavaScript when Google
created the Chrome V8 Engine. The V8 engine is an open source high-
performance JavaScript engine, written in C++ and used in the Chrome
browser and powers Node JS. The performance outmatched any engine that
came before it mainly because it combines 2 parts of the engine, the
interpreter and the compiler. Today, all major engines use this same
technique.
Go Back to Table of Contents Page 6 of 93, Ss zTMTHE PARSER
Parsing is the process of analyzing the source code, checking it for errors, and breaking it
up into parts.
THE AST
The parser produces a data structure called the Abstract Syntax Tree or AST. AST is a
tree graph of the source code that does not show every detail of the original syntax, but
contains structural or content-related details. Certain things are implicit in the tree and
do not need to be shown, hence the title abstract.
THE INTERPRETER
‘An interpreter directly executes each line of code line by line, without requiring them to
be compiled into a machine language program. Interpreters can use different strategies
to increase performance. They can parse the source code and execute it immediately,
translate it into more efficient machine code, execute precompiled code made by a
compiler, or some combination of these. In the V8 engine, the interpreter outputs
bytecode.
Nifty Snippet: The first JavaScript engine was written by Brendan Eich, the
creator of JavaScript, in 1995 for the Netscape navigator web browser.
Originally, the JavaScript engine only consisted of an interpreter. This later
evolved into the SpiderMonkey engine, still used by the Firefox browser.
THE COMPILER
The compiler works ahead of time to convert instructions into a machine-code or lower-
level form so that they can be read and executed by a computer. It runs all of the code
and tries to figure out what the code does and then compiles it down into another
language that is easier for the computer to read. Have you heard of Babel or TypeScript?
They are heavily used in the Javascript ecosystem and you should now have a good idea
Go Back to Table of Contents Page 7 of 93, Ss zTMof what they are. Babel is a Javascript compiler that takes your modern JS code and
returns browser compatible JS (older JS code). Typescript is a superset of Javascript that
compiles down to Javascript. Both of these do exactly what compilers do. Take one
language and convert into a different one!
THE COMBO
In modern engines, the interpreter starts reading the code line by line while
the profiler watches for frequently used code and flags then passes is to the compiler to
be optimized. In the end, the JavaScript engine takes the bytecode the interpreter
outputs and mixes in the optimized code the compiler outputs and then gives that to the
computer. This is called "Just in Time" or JIT Compiler.
Nifty Snippet: Back in 1995 we had no standard between the browsers for
compiling JavaScript. Compiling code on the browser or even ahead of time
was not feasible because all the browsers were competing against each
other and could not agree on an executable format. Even now, different
browsers have different approaches on doing things. Enter WebAssembly a
standard for binary instruction (executable) format. Keep your eye on
WebAssembly to help standardize browsers abilities to execute JavaScript in
the future! WebAssemby
WRITING OPTIMIZED CODE
We want to write code that helps the compiler make its optimizations, not work against
it making the engine slower.
Memoization
Memoization is a way to cache a return value of a function based on its parameters. This
makes the function that takes a long time run much faster after one execution. If the
parameter changes, it will still have to reevaluate the function.
Go Back to Table of Contents Page 8 of 93, Ss ZTmCry
esta)
console
nee
ceo mst
Peres]
reste
arena
Poss CCDS Cet sat
if (n in cache) {
return cache[n]
Pees
Coa mr ait ia
erect iay]
ee Tac a]
}
+
eee
oes
enon
Peet
Reon
Here are a few things you should avoid when writing your code if possible:
+ eval()
* arguments
* for in
Go Back to Table of Contents Page 9 of 93,° with
« delete
There are a few main reasons these should be avoided.
JavaScript Hidden Classes and Inline Caching in V8
Managing Arguments
Inline Caching
Ceca
Ure Ie}
Se Sem aU Crt eee
SUR amC a state eer?
If this code gets optimized to return only 1 name, then the computer would have to do a
lot more work if you needed to return a different user.
Hidden Classes
acum Kean D IE
Cem kenero
new Animal(3, 4);By setting these values in a different order than they were instantiated, we are making
the compiler slower because of hidden classes. Hidden classes are what the compiler
uses under the hood to say that these 2 objects have the same properties. If values are
introduced in a different order than it was set up in, the compiler can get confused and
think they don't have a shared hidden class, they are 2 different things, and will slow
down the computation. Also, the reason the delete keyword shouldn't be used is
because it would change the hidden class.
Coane amet
Peestistt a
Te esata
el
ee
eee!
Managing Arguments
There are many ways using arguments that can cause a function to be unoptimizable. Be
very careful when using arguments and remember:
Safe Ways to Use Arguments
* arguments.length
* arguments{i] when i is a valid integer
+ NEVER use arguments directly without .length or [i]
« STRICTLY fn.applyly, arguments) is ok
S371
Go Back to Table of Contents Page 11 of 93CALL STACK AND MEMORY HEAP
The JavaScript engine does a lot of work for us, but 2 of the biggest jobs are reading and
executing it. We need a place to store and write our data and a place to keep track line
by line of what's executing, That's where the call stack and the memory heap come in.
Memory Heap
The memory heap is a place to store and write information so that we can use our
memory appropriately. It is a place to allocate, use, and remove memory as needed.
Think of it as a storage room of boxes that are unordered.
ee te nee
een
eae)
Ena)
ea ae
eoianr rf
airs
S3zm
Go Back to Table of Contents Page 12 of 93Call Stack
The call stack keeps track of where we are in the code, so we can run the program in
order.
Things are placed into the call stack on top and removed as they are finished. It runs in a
first in last out mode. Each call stack can point to a location inside the memory heap. In
the above snippet the call stack looks like this (see next page)
Z™M
Go Back to Table of Contents Page 13 of 93Cred
Meares
Tae ne
Se eee ea
C
Cee eee ORT)
Con
y
NNR
Ae eC Te aa eC OT
Preto ees
anonymous) ;
We
Eira OMT eee ae)
(
Pend
Cine
1
nas
calculateQ
Con
y
eNNmS a
Com SUr Tabane re Re mY
eNNmS a
Go Back to Table of Contents Page 14 of 93STACK OVERFLOW
So what happens if you keep calling functions that are nested inside each other? When
this happens it’s called a stack overflow.
Nifty Snippet: Did you know, Google has hard-coded recursion into their
program to throw your brain for a loop when searching recursion?
Google —_reausion
Did you mean: recursion
Garbage Collection
JavaScript is a garbage collected language. If you allocate memory inside of a function,
JavaScript will automatically remove it from the memory heap when the function is done
being called. However, that does not mean you can forget about memory leaks. No
system is perfect, so it is important to always remember memory management.
JavaScript completes garbage collection with a mark and sweep method
Z™M
Go Back to Table of Contents Page 15 of 93Mark and Sweep Method
Pea)
In the example above a memory leak is created, By changing the variable person from
an object to a string, it leaves the values of first and last in the memory heap and does
not remove it. This can be avoided by trying to keep variables out of the global
namespace, only instantiate variables inside of functions when possible. JavaScript is
a single threaded language, meaning only one thing can be executed at a time. It only
has one call stack and therefore it is a synchronous language.
Go Back to Table of Contents Page 16 of 93 Ss ZTmSynchronous
So, what is the issue with being a single threaded language? Lets's start from the
beginning. When you visit a web page, you run a browser to do so (Chrome, Firefox,
Safari, Edge). Each browser has its own version of JavaScript Runtime with a set of Web
API's, methods that developers can access from the window object. In a synchronous
language, only one thing can be done at a time. Imagine an alert on the page, blocking
the user from accessing any part of the page until the OK button is clicked. If everything
in JavaScript that took a significant amount of time, blocked the browser, then we would
have a pretty bad user experience. This is where concurrency and the event loop come
in.
Event Loop and Callback Queue
When you run some JavaScript code in a browser, the engine starts to parse the code.
Each line is executed and popped on and off the call stack. But, what about Web API's?
Web API's are not something JavaScript recognizes, so the parser knows to pass it off to
the browser for it to handle. When the browser has finished running its method, it puts
what is needed to be ran by JavaScript into the callback queue. The callback queue
cannot be ran until the call stack is completely empty. So, the event loop is constantly
checking the call stack to see if it is empty so that it can add anything in the callback
queue back into the call stack. And finally, once it is back in the call stack, it is ran and
then popped off the stack.
Go Back to Table of Contents Page 17 of 93 Ss ZTmconsole. log¢"1");
Peee es 1a mec
oats
CO eer)
Coa)
eesti ee Te ee
SES ae ee eae
Cu CaTT,
console. log¢"1");
ona
Com ara Rar
i
Coote
In the last example, we get the same output. How does this work if it waits 0 seconds?
The JavaScript engine will still send off the setTimeout() to the Web AP! to be ran and it
will then go into the callback queue and wait until the call stack is empty to be ran. So,
we end up with the exact same end point.
Z™M
Go Back to Table of Contents Page 18 of 93JS Runtime Playground
TR ud Tay
%
Les.
a
What the heck is the event loop anyway? | Philip Roberts | JSConf EU (link to YouTube)
Nifty Snippet: Until 2009, JavaScript was only run inside of the browser.
That is when Ryan Dahl decided it would be great if we could use JavaScript
to build things outside the browser. He used C and C++ to build an
executable (exe) program called Node JS. Node JS is a JavaScript runtime
environment built on Chrome's V8 engine that uses C++ to provide the event
loop and callback queue needed to run asynchronous operations
inlay ery
pLication | | NODE.JS
APPLICATION | | NODE:
Z™M
Go Back to Table of Contents Page 19 of 932020 Update = Deno
SOR ee erase Uea
10 Things | Regret About Node.js - Ryan Dah (link to YouTube)
The very same Ryan Dahl then gave a talk back in 2018, 10 Things | Regret About
Node.js which led to the recent release of his new (and improved) JavaScript and
TypeScript called Deno which aims to provide a productive and secure scripting
environment for the modern programmer. It is built on top of V8, Rust, and TypeScript.
If you're interested in learning Deno, Zero To Mastery instructors, Andrei
Neagoie and Adam Odziemkowski (also an official Deno contributor), released the
very first comprehensive Deno course.
Go Back to Table of Contents Page 20 of 93 Ss zTMJob Queue
The job queue or microtask queue came about with promises in ES6. With promises we
needed another callback queue that would give higher priority to promise calls. The
JavaScript engine is going to check the job queue before the callback queue.
ence att ence aoe
setTimeout(()
Caer
On
Peano)
SCaaey
> Queue ~ Microtask Queu
SOG TaD ten 3 esa
eae By
een ac
S371
Go Back to Table of Contents Page 21 of 933 Ways to Promise
There are 3 ways you could want promises to resolve, parallel (all together), sequential
(1 after another), or a race (doesn't matter who wins).
Cet)
eer Gt ICSD
onst promises = [a), bO, OI;
Tea seen nae ol ee ae Co
Se Reece see Ce edge a
Pee sc)
const output1 = await
ene aon
eae ear on
Sete Rear Coes CMe Cae Merc cd Messy on
PucoCumTO nt
st promises = [a(), bO, cO1;
eee eer ne eeC leo
eturn “race is done: ${output1}*;
roar)
aca
(aa)
Se ee]
Pea Ree Cae ai:
Go Back to Table of Contents Page 22 of 93Threads, Concurrency, and Parallelism
Even though JavaScript is a single threaded language, there are worker threads that
work in the background that don't block the main thread. Just like a browser creates a
new thread when you open a new tab. The workers work through messages being sent,
but don't have access to the full program.
Web Workers
‘Scaling NodeJS
Multi threading
EXECUTION CONTENT
Code in JavaScript is always ran inside a type of execution context. Execution context is
simply the environment within which your code is ran. There are 2 types of execution
context in JavaScript, global or function. There are 2 stages as well to each context, the
creation and executing phase. As the JavaScript engine starts to read your code, it
creates something called the Global Execution Context.
Global Execution Context
Creation Phase
1. Global object created
2. Initializes this keyword to global
Z™M
Go Back to Table of Contents Page 23 of 93 SsExecuting Phase
3. Variable Environment created - memory space for var variables and functions
created
4, Initializes all variables to undefined (also known as hoisting) and places them
with any functions into memory
Pro
Functional Execution Context
‘A function context is created by the JavaScript engine when it sees a function call. Each
function gets its own execution context.
Creation Phase
1. Argument object created with any arguments
2. Sets this to the global object unless in strict mode, where it’s undefined
Executing Phase
3. Variable Environment created - memory space for variable and functions created
4, Initializes all variables to undefined and places them into memory with any new
functions
Z™M
Go Back to Table of Contents Page 24 of 93erties acumen seen ie aoe
rast ea
ene tee ee
return “argument 1 is: ${argi} and argument 2 is: ${arg2}°;
", "world";
Fe aC ee
PC eC R rae ee a)
resca Of
Coe CN er Ty ae
Te Pu
Dee OR ere
aac) Cargl, arg2) {
Con Cag tee Te
console. log(Array. fromCarguments));
3
UOC aC
eu
ae Ce a
cata) (emer Torn
Ci ae ear Le
console. Log(Array. fromCarguments));
DOES Cue eS
eas
ead
Go Back to Table of Contents Page 25 of 93The keyword arguments can be dangerous to use in your code as is. In ES6, a few
methods were introduced that can help better use arguments.
Arrow Functions
Some people think of arrow functions as just being syntactic sugar for a
regular function, but arrow functions work a bit differently than a regular
function. They are a compact alternative to a regular function, but also
without its own bindings to this, arguments, super,
or new.target keywords. Arrow functions cannot be used as constructors
and are not the best option for methods.
HOISTING
Hoisting is the process of putting all variable and function declarations into memory
during the compile phase. In JavaScript, functions are fully hoisted, var variables are
hoisted and initialized to undefined, and let and const variables are hoisted but not
initialized a value. Var variables are given a memory allocation and initialized a value of
undefined until they are set to a value in line. So if a var variable is used in the code
before it is initialized, then it will return undefined, However, a function can be called
from anywhere in the code base because it is fully hoisted. If let and const are used
Z™M
Go Back to Table of Contents Page 26 of 93 Ssors ooo eat
aston
Crem CC
on
Pesta carat
Pest) O
Co Ceres CC
Gaal
aac)
Coote
uaCunO ne
C
ina Cer AZ}
Ce cO PH
ECC atstue meee)
Sree ee
eat CCR eee a)
ord astO ns
eee aC esa eee er ae
Coa Qatar mere es
Wa CR aa aCe ae cae
Slee at eeerE
console. log(*New favorite food: ${favoriteFood}*);
before they are declared, then they will throw a reference error because they have not
Z™M
Go Back to Table of Contents Page 27 of 93yet been initialized (continued on next page).
TAKEAWAYS
Avoid hoisting when possible. It can cause memory leaks and hard to catch
bugs in your code. Use let and const as your go to variables.
LEXICAL ENVIRONMENT
Alexical environment is basically the scope or environment the engine is currently
reading code in. A new lexical environment is created when curly brackets {} are used,
even nested brackets {(...}} create a new lexical environment. The execution context tells
the engine which lexical environment it is currently working in and the lexical scope
determines the available variables.
escent
twoC)
Lid = undefi
ee ea
S371
Go Back to Table of Contents Page 28 of 93SCOPE CHAIN
function
ad
return function f
let b
Each environment context that is created has a link outside of its lexical environment
called the scope chain. The scope chain gives us access to variables in the parent
environment (continued on next page)
Szm
Go Back to Table of Contents Page 29 of 93Macau One
cae oF
Ea A
Pe ee
Maat Mare Ont
Perey
Pesce ue
Mur Oy
sayMyName()
CCL maEE
Bran
a
ear
Sac]
In this example, all the functions have access to the global variable x, but trying to access
a variable from another function would return an error. The example below will show
how the scope chain links each function.
S3zm
Go Back to Table of Contents Page 30 of 93sole. logCb, c);
fi FindNameQ)
log¢a);
a
Po ease Ler cs
Core CRC
Ton Utelelen
In this example, you can see that the functions only get access to the variables in their
parent container, not a child. The scope chain only links down the call stack, so you
almost have to think of it in reverse. It goes up to the parent, but down the call stack.
printName()
mace elo
sayMyName ()
Call stack
S371
Go Back to Table of Contents Page 31 of 93JavaScript is Weird
tee eT ee CURT
Tae Cece Ca
CET Coc i
Pert)
EC
Tae
code |
corer
Corie
Go Back to Table of Contents
Page 32 of 93
S371FUNCTION AND BLOCK SCOPE
Most programming languages are block scoped, meaning every time you see a new {}
(curly braces) is a new lexical environment. However, JavaScript is function scoped,
meaning it only creates a new local environment if it sees the keyword function on the
global scope. To give us access to block scope, in ES6 let and const were added to the
language. Using these can prevent memory leaks, but there is still an argument to be
made for using var.
S3zm
Go Back to Table of Contents Page 33 of 93LET AND CONST
Variable declarations with let and const work differently from
the var variable declaration and | wanted to take a minute to explain. When
a lexical scope is entered and the execution context is created, the engine
allocates memory for any var variable in that scope and initializes it to
undefined. The let and const variables only get initialized on the line they
are executed on and only get allocated undefined if there is no assignment
to the variable. Trying to access a let or const variable before it is declared
or outside of its block without returning it will result in a Reference Error.
IIFE - IMMEDIATELY INVOKED FUNCTION
EXPRESSION
Immediately Invoked Function Expression or more simply lIFE is a JavaScript function
that runs as soon as it is defined. Can also be referred to as a Self-Executing Anonymous
Function.
| Takeaways: Avoid polluting the global namespace or scope when possible.
Z™M
Go Back to Table of Contents Page 34 of 93THIS
W777)
Here we are
The moment has arrived, time to talk about this. What is this? Why is this so confusing?
For some, this is the scariest part of JavaScript. Well, hopefully we can clear some things
up.
| this is the object that the function is a property of
There that's simple right? Well, maybe not, what does that mean? Back in Execution
Context, we talked about how the JavaScript engine creates the global execution context
and initializes this to the global window object.
Z™M
Go Back to Table of Contents Page 35 of 93In the example above, it is easy to understand that this is equal to the window object,
but what about inside of function a? Well, what object is function a apart of? In the dev
tools, if you expand the window object and scroll down the list, you will see a() is a
method on the window object. By calling a(), you are essentially saying window.a() to
the console.
apes
as ee
Peate net
ee et any
console. log(this.property);
eo oF
ae easy
this refers to whatever is on the left of the . (dot) when calling a method
Still confused? Try this
urea ta) Of
Un Ce Teen
Ceara
Coa Sea
name: "Obj 1",
prea
ase
Crea ed
prea
Go Back to Table of Contents Page 36 of 93Another way to look at this is to check which object called it.
Carri
Sa eas
ora mnr(¢
Here is this 4 ways:
+ new keyword binding - the new keyword changes the meaning of this to be the
object that is being created.
« implicit binding - "this" refers to the object that is calling it. It is implied, without
doing anything it's just how the language works.
+ explicit binding - using the "bind" keyword to change the meaning of "this".
* arrow functions as methods - "this" is lexically scoped, refers to it's current
surroundings and no further. However, if "this" is inside of a method's function, it
falls out of scope and belongs to the window object. To correct this, you can use a
higher order function to return an arrow function that calls "this"
S371
Go Back to Table of Contents Page 37 of 93Per
Dost CTE
ee
Coe MreaneD)
Seat eee
th , et
Toeaeal
Cary
Ce
ot
re
7
ona
ay
Coe ee)
cee
ern)
ro aaen
recess
arrow functions inside object:
Ce eet
ia a
oe
a Ort
aCe)
Pe 03
eee
aCe eee
Go Back to Table of Contents Page 38 of 93Lexical vs Dynamic Scope
A big gotcha for a lot of people working with *this is when a function is ran inside of
another function. It gets a little confusing, but we can remember who called the
function
nar 5
Biron
Tee @r Mere
Wee eas
Ter
Coat arTe
Etre
In the example above, the obj called sing() and then anotherFunc() was called within the
sing() function. In JavaScript, that function defaults to the Window object. It happens
because everything in JavaScript is lexically scoped except for the this keyword. It
doesn't matter where it is written, it matters how it is called. Changing anotherFunc()
instead to an arrow function will fix this problem, as seen below. Arrow functions do not
bind or set their own context for this. If this is used in an arrow function, it is taken from
the outside. Arrow functions also have no arguments created as functions do.
nst 0
Eon
onsole. Lo:
naa
Carre
Coase
S371
Go Back to Table of Contents Page 39 of 93Okay, last example to really solidify our knowledge of th
Sue
Cre
Ot
cia Cer aa
Of
return function() {
oc Cra
care
ior b {name: *jay', say()...}
eee meas)
O function() {console. log(this)
Cea Re ase eee
OO; Dre
Cen en eC asCui mae uo Loe
O; Eure aant)
Peta mau mest
OO; // 4 {name: "jay", say()...3
COS SCR CR Tar eee re ee
After everything is said and done, using this can still be a bit confusing. If you aren't sur
what it's referencing, just console.log(this) and see where it's pointing.
Z™M
Go Back to Table of Contents Page 40 of 93CALL, APPLY, BIND
Call
Call is a method of an object that can substitute a different object than the one it is
written on.
eae)
Cel ec e
ear ear ont
Pee es eR T es
Cea aenet
health: 30
OCMC DH
wizard.heal.call(archer, 50, 20);
sole. Log¢arch
In this example call is used to borrow the heal method from the wizard and is used on
the archer (which is actually pointing this to archer), with the optional arguments added
Apply
Apply is almost identical to call, except that instead of a comma separated list of
arguments, it takes an array of arguments.
callca
Peer ome CMT
Tree Rt Cs
Se CR i
S371
Go Back to Table of Contents Page 41 of 93Bind
Unlike call and apply, bind does not run the method it is used on, but rather returns a
new function that can then be called later.
semen
See Te A Te
Pein
Conca
Currying With Bind
Currying is breaking down a function with multiple arguments into one or more
functions that each accept a single argument.
function multiply(a, b) {
re ee
erates NCS eee eat Near (ec ee
Ciba aCe
ran bat NCSC em eater (ec ea
Cibat ana
Exercise: Find the largest number in an array
[ily By Eilg
eau se LC ee
Ceo a eee 18 re
getMaxNumberCarray);
S371
Go Back to Table of Contents Page 42 of 93Exercise 2: How would you fix this?
Cae ilar
name p
getCharacter() {
Te
nA
RONEN Ler tec Meee Case seat Caan
PON Ik TEs ea
console. log( » giveMeTheCharacterNOW()); //this should returr
eS Meal
a
ha See
Rae Rear ta
wT
OTe acne ase een TC a tas
Co CR Gre arta Oh
S371
Go Back to Table of Contents Page 43 of 93JAVASCRIPT TYPES
Brittney goes into all of the types in her basic JavaScript course notes, but decided to
take a deeper dive into types in JavaScript here.
Type Result
Undefined undefined
‘Null object*
Boolean boolean
Number number
Bigint (new in ECMAScript 2020) bigint
String string
Symbol (new in ECMAScript 2015) symbol
Function object function
Any other object object
*Null - Why does the typeof null return object? When JavaScript was first
implemented, values were represented as a type tag and a value. The
objects type tag was 0 and the NULL pointer (0x00 in most platforms)
consequently had 0 as a type tag as well. A fix was proposed that would
have made typeof null =:
‘null’, but it was rejected due to legacy code that
would have broken.
en rae
Number tries to pa
DUT
Z™M
Go Back to Table of Contents Page 44 of 93Ord 5 Cea Cney
So ae p Set
Cromer Te) Sanur Seo
typeof Symbol()
Saar
Sects
fan
Sa UL
Bema ne atta
Pa eae ata
pe tos
Nee CS Soe
rae) 8
typeof nen DateC)
Ma
Sete eect ene
typeof new BooleanCtrue)
mn Cab)
CaS
Functions
ecco nr’
eenaees
Math.sin
Go Back to Table of Contents Page 45 of 93Undefined vs Null: Undefined is the absence of definition, it has yet to be
defined, and null is the absence of value, there is no value there.
Objects in JavaScript
Objects are one of the broadest types in JavaScript, almost "everything" is an
object. MDN Standard built-in objects
Booleans can be objects (if defined with the new keyword)
Numbers can be objects (if defined with the new keyword)
Strings can be objects (if defined with the new keyword)
Dates are always objects
Maths are always objects
Regular expressions are always objects
Arrays are always objects
Functions are always objects
Objects are always objects
Primitive vs. Non Primitive
Primitive - Primitive values are defined by being immutable, they cannot be altered. The
variable assigned to a primitive type may be reassigned to a new value, but the original
value can not be changed in the same way objects can be modified. Primitives
are passed by value, meaning their values are copied and then placed somewhere else
in the memory. They are also compared by value. There are currently 7 primitive data
types in JavaScript.
« string
* number
© bigint
boolean
null
undefined
symbol
Go Back to Table of Contents Page 46 of 93 Ss ZTmNon Primitive - The only type that leaves us with is objects. Objects are able to be
mutated and their properties are passed by reference, meaning their properties are not
stored separately in memory. A new variable pointing to an object will not create a copy,
but reference the original objects location in memory. Therefore, changing the 2nd
object will also change the first.
ae
Since bott
or Te:
Coes
Sao cum rea
let arr = [1, 2, 3];
eta ea
Ce Ue
Te CET Clas
STC CC GDH
There are two ways to get around this, Object.assign() or use the spread operator {...} to
"spread" or expand the object into a new variable. By doing this, it will allow the new
variable to be modified without changing the original. However, these only create a
"shallow copy".
Shallow copy: Shallow copy is a bit-wise copy of an object. A new object is
created that has an exact copy of the values in the original object. If any of
the fields of the object are references to other objects, just the reference
addresses are copied i.e., only the memory address is copied.
> Deep copy: A deep copy copies all fields, and makes copies of dynamically
allocated memory pointed to by the fields. A deep copy occurs when an
object is copied along with the objects to which it refers.
> Understanding Deep and Shallow Copy
S371
Go Back to Table of Contents Page 47 of 93Ciara
Memory Heap
Variables Addresses | Objects
Ceres}
Tod
Peer el]
shallowObj
erste)
fee eee ers
Z™M
Go Back to Table of Contents Page 48 of 93Co ae aC I
ce
ea Ca
im
PCR
aH
Cees Cy Seat 1s
oR AC Se Me Lr 0S
Corea astm Cat IC aye
eee CLT ", originaldbj);
Ce QRS ECS
or CMG nc eMC TO CL SD
Corea CR Ges
Dee Ma er
es ay
NU
ray
Go Back to Table of Contents Page 49 of 93Nifty Snippet: if you try to check if 2 objects with the same properties are
equal with obj1 = obj2, it will return false. It does this because each object
has its own address in memory as we learned about. The easiest way to
check the contents of the objects for equality is this.
This will return true if all properties are the same.
Type Coercion
Type coercion is the process of converting one type of value into another. There are 3
types of conversion in JavaScript.
# to stringx
* to boolean
* to number
ea
Strict equals: The triple equals (===) or strict equality compares two values
without type coercion. If the values are not the same type, then the values
are not equal. This is almost always the right way to check for equality in
JavaScript, so you don't accidentally coerce a value and end up with a bug in
your program. Here is the MDN Equality Comparison page and
the ECMAScript Comparison Algorithm,
Z™M
Go Back to Table of Contents Page 50 of 93There are several edge cases that you will come in contact with in JavaScript as well.
Check out this Comparison Table if you have questions about how types are coerced.
Static vs Dynamic Typed
The major difference between static and dynamic typed languages is when the types of
variables are checked, Static typed languages (Java, C, C++, C#l) are checked during the
compile stage, so all types are known before run-time. Dynamic languages (JavaScript,
PHP, Python, Ruby, Perl) are checked on the fly, during the execution stage. Also, after
dividing the languages into dynamic and static, they are then divided again
into strong and weak typed. Weakly typed (JavaScript, PHP, C, C++) languages can make
type coercions implicitly while strongly typed (Python, Ruby, C#t, Java) do not allow
conversions between unrelated types.
THE 2 PILLARS: CLOSURES AND PROTOTYPES
Closures and Prototypal Inheritance are two things that make JavaScript special and
different from other programming languages.
Function Constructor
Functions are objects in JavaScript, which is not true for other languages. Because of
that, they can be called multiple ways, but they can also be constructors. A function
constructor creates a new object and returns it. Every JavaScript function, is actually a
function object itself.
Go Back to Table of Contents Page 51 of 93 Ss zTMCfunction() {}.contructor aaa
esha tin ae aC“
CO ae rae aia,
Coa ec) e
Cina em ene
Almost everything in JavaScript can be created with a constructor. Even basic Jav
types like numbers and strings can be created using a constructor.
Cees
Coane) (5)5
const assignFive
SRC ae uns
Coane arr ey
Coa SC ar a a
Oat Ao
Ora SC hat eA
rar
Dame cat
aero C aN
Neate ype TAL
Ceara Res
Go Back to Table of Contents Page 52 of 93Prototypal Inheritance
Almost all objects in Javascript pass down properties through a prototype chain. We call
this chain, prototypal inheritance. The child of the object "inherits" properties from its
parent. All objects in JavaScript are descended from the Object constructor unless
deliberately created or altered to not do so. The objects inherit methods and properties
from Object.prototype. The prototype property also has an accessor property
called __proto__ that creates a link between the current object and points to the object
it was created from, the "prototype".
ere Ree ears)
Prototype vs __proto__
Understanding the difference between __proto__and prototype can be quite a
confusing concept for JavaScript developers. Every function in JavaScript automatically
gets a prototype property when it is created that gives it the call, apply, and bind
methods. It doesn't really do anything with regular functions, but in constructor
S3zt™
Go Back to Table of Contents Page 53 of 93functions the prototype property allows us to add our own methods to the objects we
create. The __proto__ property is what creates the link between prototype objects, the
child inherits properties from the parent through the prototype chain. Each time a new
object is created in JavaScript, it uses the __proto__ getter function to use a built in
constructor function based on what is being created. This could be an Array, Boolean,
Date, Number, Object, String, Function, or RegExp. Each one has their own separate
properties and methods that they inherit from the constructor.
let newArr = new Array
S371
Go Back to Table of Contents Page 54 of 93Callable Object
Because functions are objects in JavaScript, this also gives them the ability to have
properties added to them. This creates a callable object, a special object that creates
properties not available on normal objects. Below is a visualization of how this works
under the hood. This code can not be ran in the console, but it is a representation of
how the object looks.
Tr RTaae
CLE
reo
EMG Nee ID)
ate)
aN re
ial
nee eee
Z™M
Go Back to Table of Contents Page 55 of 93Nifty snippet: You might hear people say "Functions are first-class citizens in
JavaScript". All this means is that functions can be passed around as if they
were a JavaScript type. Anything that can be done with other 7n hhb, can
also be done with functions. This introduces JavaScript to a whole different
type of programming called functional programming. Below are some
examples of how functions work differently in JavaScript
Tasco cua
Higher Order Functions
A Higher Order Function (HOF) is a function that either takes a function as an argument
or returns another function. There are 3 kinds of functions in JavaScript.
* function ()
* function (a,b)
* function hof() { return function () {}}
Instead of writing multiple functions that do the same thing, remember DRY (don't
repeat yourself). Imagine in the example below, if you separated each code out into
individual functions how much more code you would be writing and how much code
would be repeated.
Z™M
Go Back to Table of Contents Page 56 of 93ing Se Sad
esc UO ee
arc
for (let i = 0; i < roleAmt;
Che CO;
}
cota
Peay CURIE
Cun re
peur Ca
Cru
Ce OE TU Lats eee TH
Eee ee
Take the example below of how you can separate code out and break it down to make it
more reusable.
fiesta oe
Peer oat C Oe
re
+
or ry
Crean Na)
Cone aie
Go Back to Table of Contents Page 57 of 93Closures
Closures allow a function to access variables from an enclosing scope or environment
even after it leaves the scope in which it was declared. In other words, a closure gives
you access to its outer functions scope from the inner scope. The JavaScript engine will
keep variables around inside functions that have a reference to them, instead of
"sweeping" them away after they are popped off the call stack.
Testa)
ea
return fun
ea
cay
return functior
let s¢
returr
Soe Ty
ee Cee eS . eit Sg
randma > mother > daughter
Z™M
Go Back to Table of Contents Page 58 of 93A Fun Example with Closures
Do not run this in the console, it takes 1 day to timeout!
Two of the major reasons closures are so beneficial are memory efficiency and
encapsulation.
Z™M
Go Back to Table of Contents Page 59 of 93Memory Efficient
Using closures makes your code more memory efficient. Take the example below.
est ferron
Onan a
CeCe
Pen Urn Ca
roca Of
Coe Uae te
ea CM eke Tun
east ones
a Ucn es
Ciba saa cata
Gate ee SC Une
ster at et Lee Ge Aa
Go Back to Table of Contents Page 60 of 93Encapsulation
Encapsulation means the restriction of direct access to some of an object's components.
It hides as much as possible of an object's internal parts and only exposes the necessary
parts to run. Why use encapsulation?
* Security - Controlled access
+ Hide Implementation and Expose Behaviours
* Loose Coupling - Modify the implementation at any time
Perenest
oer
Tee ao
eo
SyateGC eae D ys
S371
Go Back to Table of Contents Page 61 of 93OBJECT ORIENTED PROGRAMMING VS
FUNCTIONAL PROGRAMMING
There are 2 basic philosophies when it comes to how you structure your programs,
object oriented and functional. Each style has its use in programming, it is not one over
the other, but merely a preference in style.
Object Oriented Programming
Object Oriented Programming, or OOP, is the idea that all code should be grouped into
"boxes" (objects) to make your program easier to read and understand. Keeping the data
encapsulated helps to keep the program organized. Each object has a state that defines
what it does and methods (functions on an object) that can use or modify the state.
Considering almost everything in JavaScript is an object, you would think this would be
easy to do. Say we want to create a game that has lots of characters that all have
different abilities. How would we go about this?
Go Back to Table of Contents Page 62 of 93 Ss zTMni
Sy ee
lea
tion() {
Ce ee aCe Scare
Sora
a catLO ne
Tse ee Ca,
ni
Paces
ies Ones
retro a rte Scere
Go Back to Table of Contents Page 63 of 93
Boy aoa
Sz™Factory Functions
As you can see, this code is already getting very repetitive and is not maintainable with
only 1 character type. Imagine adding more characters, things would get out of control
quickly. So, another way to create objects was introduced, factory functions. Factory
functions return a new object every time they are ran. This could improve the code
somewhat.
Craera@
CeO yS ceria
ote
area
Ee) ee pa aa
rT eT cag
attacks with cloth
eC oe Te
S371
Go Back to Table of Contents Page 64 of 93Stores
This is a step in the right direction, but if we added more characters, we would run into
some of the same issues again. Not only is the code not DRY, the attack method is being
created and taking up memory space for every new elf. This is not very efficient. How do
we solve this? Well, we could separate the methods out into a store.
ee
CrareceO net
cata
eR ems
eaten an LR
rere
name: name, // old wc
with ES6 as
orca
See Se CN ee aa
nia oe
S371
Go Back to Table of Contents Page 65 of 93Object.create
Having a store saved us some efficiency in memory, but this was a lot of manual work to
assign each method. So, we were given Object.create to help create this chain without
having to assign each method.
"
eee ae ee
DAE CRC eee MURS Cree
oo CCCs Cm
Cee oe eer a na
Tansee Meee een
CRG rt ates a Pract amet]
Se aCe ee eee
nae
cea ee
ra en
a eae
return newEl
Constructor Functions
Using Object.create is true prototypal inheritance, the code is cleaner and easier to read.
However, you will not see this being used in most programs. Before Object.create came
around, we had the ability to use constructor functions. Constructor functions are
exactly like the function constructor we talked about above. The number and string
functions were constructed and invoked with the new keyword and they were
capitalized. The new keyword actually changes the meaning of this for the constructor
Z™M
Go Back to Table of Contents Page 66 of 93 Ssfunction. Without new, this will point to the window object instead of the object that we
just created. It is best practice to capitalize constructor functions to help us identify
them and know to use the new keyword. Properties added to a constructor function can
only be done using the this keyword, regular variables do not get added to the object.
Pines st eee rt anne reece)
reat uaa ES CA Oe
rer OR Lan
eres Ge
Ces ea
Ree eT a
See ea
" keyword must be use
Coan eee a
Coie aa coe ene
oe eT
Rete PacsCon
ae rst
ORCC ROR CCE ny
eee cece La
3
This would need to be repeated for each method
Caster)
ee Crater en
Go Back to Table of Contents Page 67 of 93Nifty Snippet: A constructor function in JavaScript is actually just a
constructor itself
arene an
aaa Un
[ro as a)
ame as our code ab
Class
Confused yet? Prototype is a little weird and hard to read unless you really understand
your prototypal inheritance. No one really liked using the prototype way of adding
methods, so in ES6 JavaScript gave us the class keyword. However, classes in JavaScript
are not true classes, they are syntactic sugar. Under the hood, it is still using the old
prototype method. They are in fact just "special functions" with one big difference,
functions are hoisted and classes are not. You need to declare your class before it can be
used in your codebase. Classes also comes with a new method, the constructor that
creates and instantiates an object created with class. Classes are able to be extended
upon using the extends keyword, allowing subclasses to be created. If there is a
constructor present in the extended class, the super keyword is needed to link the
constructor to the base class. You can check if something is inherited from a class by
using the keyword instanceof to compare the new object to the class
Z™M
Go Back to Table of Contents Page 68 of 93 Sstn
(Cs
Cee ea
Ce eC
Pee aS Cen
Streetcar) fi
re ue NE
Uno
POSS OMe Re ee eee
ee ey
tre eure rt
re ect
Eun
Eee ee Ce
Pest ec
Coase ot eee ae @n Tot Cea
const gruul = new Ogre("Gruul", "club", "gra;
ee AA ee)
cia PCR aaa rot
Carseat
eee Greg
Presta
Go Back to Table of Contents Page 69 of 93Private and public fields
Most class based languages have the ability to create either public or private fields
within a class. Adding these to classes in JavaScript is still an experimental feature in
development. Support in browsers is limited, but can be implemented with systems like
Babel. Public declarations are set above the constructor and can be used within the
class, but do not get added to a new instance. The private declarations are set with
the # sign in front of the variable and are only accessible within that class, they cannot
be accessed or changed from outside.
Wetter cate
ree tec Ca
rae
Prec
Cea amc DE
cies
this.width = width;
ate declarat
ree eta
EC eae
Reece ame oy
Gee
eC gen
So, did we obtain perfect object oriented programming? Well, that is up for debate. It is
really up to you the developer to decide which style of writing you like best. We did
learn that object oriented programming helps make you code more understandable,
easy to extend, easy to maintain, memory efficient, and DRY!
S371
Go Back to Table of Contents Page 70 of 93Nifty Snippet: Why didn't Eich just add classes to JavaScript in the
beginning?
"Wf had done classes in JavaScript back in May 1995, | would have been told
that it was too much like Java or the JavaScript was competing with Java
was under marketing orders to make it look like Java but not make it too big
for its britches ... [it] needed to be a silly little brother language." —Brendan
Eich
4 PILLARS OF OOP
* Encapsulation - Organizes code into containers that relate to each other and makes
it easier to maintain and reuse.
* Abstraction - Hides the complexity from the user by doing the method calculations
behind the scenes.
* Inheritance - Gives the properties of a class to another class, keeping code DRY and
saving on memory space.
* Polymorphism - The ability of an object to take on many forms allowing methods to
be used differently by different classes.
Go Back to Table of Contents Page 71 of 93 Ss ZTmFUNCTIONAL PROGRAMMING
Functional programming has the same goals in mind as object oriented programming, to
keep your code understandable, easy to extend, easy to maintain, memory efficient, and
DRY. Instead of objects, it uses reusable functions to create and act on data. Functional
program is based on a separation of concerns similar to object oriented programming
However, in functional programming there is a complete separation between the data
and the behaviors of a program. There is also an idea that once something is created, it
should not be changed, being immutable. Unlike OOP, shared state is avoided functional
programming works on the idea of pure functions.
Pure Functions
‘A pure function has no side effects to anything outside of it and given the same input
will always output the same value. They do not change any data passed into them, but
create new data to return without altering the original. However, it is not possible to
have 100% pure functions. At some point you need to interact with the dom or fetch an
api. Even console.log makes a function unpure because it uses the window object
outside of the function. Fact is a program cannot exist without side effects. So, the goal
of functional programming is to minimize side effects by isolating them away from the
data.
Build lots of very small, reusable and predictable pure functions that do the following:
* Complete 1 task per function.
Do not mutate state.
Do not share state.
Be predictable.
Be composable, one input and one output.
Be pure if possible.
Return something.
Referential transparency
One important concept of functional programming is referential transparency, the
ability to replace an expression with the resulting value without changing the result of
the program
Go Back to Table of Contents Page 72 of 93 Ss zTMCen DD HZABCS
eC RCC mri
Ce CRC et
44
Idempotence
Idempotence is another important piece of functional programming. It is the idea that
given the same input to a function, you will always return the same output. The function
could be used over and over again and nothing changes. This is how you make your code
predictable
Imperative vs Declarative
Imperative programming tells the computer what to do and how to complete it.
Declarative programming only tells the computer what to do, but not how to do things.
Humans are declarative by nature, but computers typically need more imperative type
programming. However, using higher level languages like JavaScript is actually being less
declarative. This is important in function programming because we want to be more
declarative to better understand our code and let the computer handle the dirty work of
figuring out the best way to do something.
S371
Go Back to Table of Contents Page 73 of 93