JavaScript For Beginners
JavaScript For Beginners
Table of Contents
Preface
Introduction to JavaScript
History
Just JavaScript
Syntax
Semicolons
Values
Variables
Types
Expressions
Operators
Precedence
Comparisons
Conditionals
Strings
Arrays
Loops
Functions
Arrow Functions
Objects
Object properties
Object methods
Classes
Inheritance
Asynchonous Programming and Callbacks
Promises
pg. 2
Async and Await
Variables scope
Conclusion
pg. 3
Preface
The JavaScript Beginner's Handbook follows the 80/20 rule: learn in 20% of
the time the 80% of a topic.
This book does not try to cover everything under the sun related to JavaScript.
It focuses on the core of the language, trying to simplify the more complex
topics.
I hope the contents of this book will help you achieve what you want: learn the
basics of JavaScript.
@ambijamesonline
Enjoy!
pg. 4
Introduction to JavaScript
JavaScript is one of the most popular programming languages in the world.
websites
web applications
server-side applications using Node.js
but JavaScript is not limited to these things, and it can also be used to
It can basically do anything. It's so popular that everything new that shows up
is going to have JavaScript integration at some point.
high level: it provides abstractions that allow you to ignore the details of
the machine where it's running on. It manages memory automatically with
a garbage collector, so you can focus on the code instead of managing
memory like other languages like C would need, and provides many
constructs which allow you to deal with highly powerful variables and
objects.
dynamic: opposed to static programming languages, a dynamic language
executes at runtime many of the things that a static language does at
compile time. This has pros and cons, and it gives us powerful features
like dynamic typing, late binding, reflection, functional programming,
object runtime alteration, closures and much more. Don't worry if those
things are unknown to you - you'll know all of those at the end of the
course.
dynamically typed: a variable does not enforce a type. You can reassign
pg. 5
any type to a variable, for example, assigning an integer to a variable that
holds a string.
loosely typed: as opposed to strong typing, loosely (or weakly) typed
languages do not enforce the type of an object, allowing more flexibility
but denying us type safety and type checking (something that TypeScript -
which builds on top of JavaScript - provides)
interpreted: it's commonly known as an interpreted language, which
means that it does not need a compilation stage before a program can
run, as opposed to C, Java or Go for example. In practice, browsers do
compile JavaScript before executing it, for performance reasons, but this
is transparent to you: there is no additional step involved.
multi-paradigm: the language does not enforce any programming
paradigm, unlike Java for example, which forces the use of object-
oriented programming, or C that forces imperative programming. You can
write JavaScript using an object-oriented paradigm, using prototypes and
the new (as of ES6) classes syntax.
pg. 6
History
Made in 1995, JavaScript has gone far since its unassuming beginnings.
It was the first prearranging language that was upheld locally by internet
browsers, and gratitude to this it acquired an upper hand over some other
languages and today it's yet the just prearranging language that we can use to
fabricate Web Applications.
In the beginning, JavaScript was not almost strong as it is today, and it was
mostly utilized for extravagant movements and the wonder referred to at the
time as Dynamic HTML.
With the developing necessities that the web stage requested (and keeps on
requesting), JavaScript had the obligation to develop also, to oblige the
requirements of one of the most generally utilized biological systems of the
world.
JavaScript is currently likewise the language fueling data sets and a lot more
applications, and it's even conceivable to foster inserted applications, portable
applications, TV sets applications and considerably more. Which began as a
minuscule language inside the program is currently the most well-known
language on the planet.
$107,529 Per/year
pg. 7
Where does JavaScript run?
Now and then it's difficult to isolate JavaScript from the elements of the climate it
is utilized in.
For instance, the console.log () line you can find in many code models isn't
JavaScript. All things considered, it's important for the tremendous library of
APIs gave to us in the program. Similarly, on the server it very well may be in
some cases hard to isolate the JavaScript language highlights from the APIs
given by Node.js.
Is a specific component given by React or Vue? Or on the other hand is it "plain
JavaScript", or "vanilla JavaScript" as frequently called?
In this book I talk about JavaScript, the language.
Without muddling your learning interaction with things that are outside of it, and
given by outer biological systems.
pg. 8
Syntax
In this little introduction I want to tell you about 5 concepts:
white space
case sensitivity
literals
identifiers
comments
White space
JavaScript does not consider white space meaningful. Spaces and line breaks
can be added in any fashion you might like, even though this is in theory.
In practice, you will most likely keep a well-defined style and adhere to what
people commonly use, and enforce this using a linter or a style tool such as
Prettier.
Case sensitive
JavaScript is case sensitive. A variable named something is different from
Something.
Literals
We define as literal a value that is written in the source code, for example, a
number, a string, a boolean or also more advanced constructs, like Object
Literals or Array Literals:
pg. 9
5
'Test' true
['a', 'b']
{color: 'red', shape: 'Rectangle'}
Identifiers
An identifier is a sequence of characters that can be used to identify a
variable, a function, an object. It can start with a letter, the dollar sign $ or an
underscore _, and it can contain digits. Using Unicode, a letter can be any
allowed char, for example, an emoji.
Best
best
BEST
_best
Best1
$best
Some names are reserved for JavaScript internal use, and we can't use them
as identifiers.
Comments
Comments are one of the most important parts of any program. In any
programming language. They are important because they let us annotate the
code and add important information that otherwise would not be available to
other people (or ourselves) reading the code.
pg. 10
Like this:
// a comment
true //another comment
/* some kind of
comment
*/
pg. 11
Semicolons
Every line in a JavaScript program is optionally terminated using semicolons.
In most cases, you can omit semicolons altogether from your programs.
This fact is very controversial, and you'll always find code that uses
semicolons and code that does not.
pg. 12
Values
A hello string is a value. A number like 12 is a value.
hello and 12 are values. string and number are the types of those values.
The type is the kind of value, its category. We have many different types in
JavaScript, and we'll talk about them in detail later. Each type has its own
characteristics.
pg. 13
Variables
A variable is a value assigned to an identifier, so you can reference and use it
later in the program.
const a = 0
let a = 0
const defines a constant reference to a value. This means the reference cannot
be changed. You cannot reassign a new value to it.
const a = 0 a = 1
Because you'll get an error: TypeError: Assignment to constant variable... On the other
let a = 0 a = 1
pg. 14
const does not mean "constant" in the way some other languages like C mean.
It does not mean the value cannot change - it means it cannot be reassigned.
If the variable points to an object or an array (we'll see more about objects and
arrays later) the content of the object or the array can freely change.
const a = 0
let a
a=0
const a = 1, b = 2 let c = 1,
d=2
But you cannot redeclare the same variable more than one time:
let a = 1 let a
=2
My advice is to always use const and only use let when you know you’ll need to
reassign a value to that variable. Why? Because the less power our code has,
the better. If we know a value cannot be reassigned, it's one less source for
bugs.
Now that we saw how to work with const and let, I want to mention var.
pg. 15
Until 2015, var was the only way we could declare a variable in JavaScript.
Today, a modern codebase will most likely just use const and let. There are
some fundamental differences which are detailed here, in this post by Flavio
but if you're just starting out, you might not care about. Just use const and let.
pg. 16
Types
Variables in JavaScript do not have any type attached.
Once you assign a value with some type to a variable, you can later reassign
the variable to host a value of any other type, without any issue.
Primitive types
Primitive types are
numbers
strings
booleans
symbols
Object types
Any value that's not of a primitive type (a string, a number, a boolean, null or
undefined) is an object.
Object types have properties and have methods that can act on those
properties.
pg. 17
Expressions
An expression is a single unit of JavaScript code that the JavaScript engine
can evaluate, and return a value.
2
0.02
'something'
True false
undefined
1/2
i++
i -= 2
i*2
a && b a
|| b
!a
pg. 18
More advanced expressions involve objects, functions, and arrays, and I'll
introduce them later.
pg. 19
Operators
Operators allow you to get two simple expressions and combine them to form
a more complex expression.
We can classify operators based on the operands they work with. Some
operators work with 1 operand. Most with 2 operands. Just one operator works
with 3 operands.
In this first introduction to operators, we'll introduce the operators you are most
likely familiar with: binary operators.
let b = 2
Let's now introduce another set of binary operators that you already familiar
with, from basic math.
The + operator also serves as string concatenation if you use strings, so pay
attention:
const three = 1 + 2
three + 1 // 4 'three' + 1 //
three1
pg. 20
const two = 4 - 2
If you divide by zero, JavaScript does not raise any error but returns the
Infinity value (or -Infinity if the value is negative).
1 / 0 //Infinity
-1 / 0 //-Infinity
A reminder by zero is always NaN, a special value that means "Not a Number":
1 % 0 //NaN
-1 % 0 //NaN
1 * 2 //2
-1 * 2 //-2
pg. 21
The exponentiation operator (**)
Raise the first operand to the power second operand
1 ** 2 //1
2 ** 1 //2
2 ** 2 //4
2 ** 8 //256
8 ** 2 //64
pg. 22
Precedence
Every complex statement with multiple operators in the same line will introduce
precedence problems.
let a = 1 * 2 + 5 / 2 % 2
Some operations have more precedence than the others. The precedence
rules are listed in this table:
Operator Description
* / % multiplication/division
+ - addition/subtraction
= assignment
Operations on the same level (like + and -) are executed in the order they are
found, from left to right.
Following these rules, the operation above can be solved in this way:
let a = 1 * 2 + 5 / 2 % 2
let a = 2 + 5 / 2 % 2
let a = 2 + 2.5 % 2
let a = 2 + 0.5 let a =
2.5
pg. 23
Comparisons
After assignment and math operators, the third set of operators I want to
introduce is conditional operators.
You can use the following operators to compare two numbers, or two strings.
Example:
let a = 2
a >= 1 //true
Note that we also have == and != in JavaScript, but I highly suggest to only use
=== and !== because they can prevent some subtle problems.
pg. 24
Conditionals
With the comparison operators in place, we can talk about conditionals.
if (true) {
//do something
}
if (false) {
//do something (? never ?)
}
The conditional checks the expression you pass to it for true or false value. If
you pass a number, that always evaluates to true unless it's 0. If you pass a
string, it always evaluates to true unless it's an empty string. Those are
general rules of casting types to a boolean.
Did you notice the curly braces? That is called a block, and it is used to group
a list of different statements.
A block can be put wherever you can have a single statement. And if you have
a single statement to execute after the conditionals, you can omit the block,
and just write the statement:
if (true) doSomething()
pg. 25
Else
You can provide a second part to the if statement: else.
if (true) {
//do something
} else {
//do something else
}
Since else accepts a statement, you can nest another if/else statement inside
it:
if (a === true) {
//do something
} else if (b === true) {
//do something else
} else {
//fallback
}
pg. 26
Strings
A string is a sequence of characters.
I personally prefer single quotes all the time, and use double quotes only in
HTML to define attributes.
You can determine the length of a string using the length property of it:
''.length //0
pg. 27
"My name is " + name //My name is Ambison
Once a template literal is opened with the backtick, you just press enter to
create a new line, with no special characters, and it's rendered as-is:
string
is awesome! `
Template literals are also great because they provide an easy way to
interpolate variables and expressions into strings.
pg. 28
Arrays
An array is a collection of elements.
const a = [] const a =
Array ()
The first is using the array literal syntax. The second uses the Array built-in
function.
const a = [1, 2, 3]
const a = Array. Of (1, 2, 3)
pg. 29
You can access any element of the array by referencing its index, which starts
from zero:
a [0] //1
a [1] //2
a [2] //3
You can initialize a new array with a set of values using this syntax, which first
initializes an array of 12 elements, and fills each element with the 0number:
You can get the number of elements in the array by checking its length
property:
Note that you can set the length of the array. If you assign a bigger number
than the arrays current capacity, nothing happens. If you assign a smaller
number, the array is cut at that position:
const a = [1, 2, 3]
a //[ 1, 2, 3 ]
a.length = 2
a //[ 1, 2 ]
a.push(4)
pg. 30
We can add an element at the beginning of an array using the unshift()
method:
a.unshift(0) a.unshift(-2,
-1)
a.pop()
We can remove an item from the beginning of an array using the shift()
method:
a.shift()
const a = [1, 2]
const b = [3, 4]
const c = a.concat(b) //[1,2,3,4]
a //[1,2]
b //[3,4]
You can also use the spread operator ( ........) in this way:
const a = [1, 2]
const b = [3, 4]
pg. 31
How to find a specific item in the array
You can use the find() method of an array:
Returns the first item that returns true. Returns undefined if the element is not
found.
The above line will return the first element in the array that has id === my_id.
findIndex() works similarly to find() , but returns the index of the first item that
returns true, and if not found, it returns undefined:
a.includes(value)
a.includes(value, i)
pg. 32
Loops
Loops are one of the main control structures of JavaScript.
With a loop we can automate and repeat indefinitely a block of code, for how
many times we want it to run.
while loops
for loops
for..of loops
while
The while loop is the simplest looping structure that JavaScript provides us.
We add a condition after the while keyword, and we provide a block that is run
until the condition evaluates to true.
Example:
You can interrupt a while loop using the break keyword, like this:
while (true) {
if (somethingIsTrue) break
}
pg. 33
and if you decide that in the middle of a loop you want to skip the current
iteration, you can jump to the next iteration using continue:
while (true) {
if (somethingIsTrue) continue
Very similar to while, we have do..while loops. It's basically the same as
while, except the condition is evaluated after the code block is executed. This
Example:
for
The second very important looping structure in JavaScript is the for loop.
Example:
pg. 34
}
Just like with while loops, you can interrupt a you for loop using break and
can fast forward to the next iteration of a for loop using continue .
for...of
This loop is relatively recent (introduced in 2015) and it's a simplified version of
the for loop:
pg. 35
Functions
In any moderately complex JavaScript program, everything happens inside
functions.
What is a function?
function getData() {
// do something
}
A function can be run any times you want by invoking it, like this:
getData()
function getData() {
//do something
}
function getData(color) {
//do something
}
pg. 36
function getData(color, age) {
//do something
}
getData('green', 24)
getData('black')
although the conditional will also be true if age is null, 0 or an empty string.
You can have default values for parameters, in case they are not passed:
pg. 37
}
You can pass any value as a parameter: numbers, strings, booleans, arrays,
objects, and functions.
A function has a return value. By default, a function returns undefined, unless you
add a return keyword with a value:
function getData() {
// do something
return 'hi!'
}
We can assign this return value to a variable when we invoke the function:
function getData() {
// do something
return 'hi!'
}
result now holds a string with the the hi! value. You
To return multiple values, you can return an object, or an array, like this:
pg. 38
dosomething()
return 'test'
}
The nested function cannot be called from the outside of the enclosing
function.
pg. 39
Arrow Functions
Arrow functions are a recent introduction to JavaScript.
They are very often used instead of "regular" functions, the one I described in
the previous chapter. You'll find both forms used everywhere.
Visually, they allow you to write functions with a shorter syntax, from:
function getData() {
//...
}
to
() => {
//...
}
pg. 40
let getData = function() {
//...
}
getData()
If the function body contains just a single statement, you can omit the
parentheses and write all on a single line:
If you have one (and just one) parameter, you could omit the parentheses
completely:
Arrow functions allow you to have an implicit return: values are returned
without having to use the return keyword.
getData() //'test'
pg. 41
Like with regular functions, we can have default parameters:
You can have default values for parameters, in case they are not passed:
Arrow functions can contain other arrow function, or also regular functions.
They are very similar, so you might ask why they were introduced? The big
difference with regular functions is when they are used as object methods.
This is something we'll soon investigate.
pg. 42
Objects
Any value that's not of a primitive type (a string, a number, a boolean, a
symbol, null, or undefined) is an object.
const car = {
This is the object literal syntax, which is one of the nicest things in JavaScript.
You can also initialize an object using the new keyword before a function with a
capital letter. This function serves as a constructor for that object. In there, we
can initialize the arguments we receive as parameters, to setup the initial state
of the object:
pg. 43
myCar.model //'Fiesta'
If you assign a variable the same value of another, if it's a primitive type like a
number or a string, they are passed by value:
Even arrays or functions are, under the hoods, objects, so it's very important to
understand how they work.
pg. 44
Object properties
Objects have properties, which are composed by a label associated with a
value.
The value of a property can be of any type, which means that it can be an
array, a function, and it can even be an object, as objects can nest other
objects.
const car = {
here we have a car object with a property named color, with value blue.
Labels can be any string, but beware special characters: if I wanted to include
a character not valid as a variable name in the property name, I would have
had to use quotes around it:
Invalid variable name characters include spaces, hyphens, and other special
characters.
pg. 45
As you see, when we have multiple properties, we separate each property with
a comma.
car.color //'blue'
The second (which is the only one we can use for properties with invalid
names), is to use square brackets:
car.brand //undefined
car.brand.name
or
car['brand']['name']
pg. 46
You can set the value of a property when you define the object.
car.color = 'yellow'
car['color'] = 'red'
car.model = 'Fiesta'
car.model //'Fiesta'
delete car.brand
pg. 47
Object methods
I talked about functions in a previous chapter.
Functions can be assigned to a function property, and in this case, they are
called methods.
In this example, the start property has a function assigned, and we can invoke it
by using the dot syntax we used for properties, with the parentheses at the
end:
car.start()
Inside a method defined using a function() {} syntax we have access to the object
instance by referencing this.
car.start()
pg. 48
It's important to note this distinction between regular functions and arrow
functions: we don't have access to this if we use an arrow function:
car.start()
This is the reason why regular functions are often used as object methods.
car.goTo('Rome')
pg. 49
Classes
We talked about objects, which are one of the most interesting parts of
JavaScript.
What are classes? They are a way to define a common pattern for multiple
objects.
We can create a class named Person (note the capital P, a convention when
using classes), that has a name property:
Ambison.name = 'Ambison'
pg. 50
Ambison.name
There is a special method called constructor() that we can use to initialize the class
properties when we create a new object instance.
class Person {
constructor(name) {
this.name = name
}
hello() {
return 'Hello, I am ' + this.name + '.'
}
}
pg. 51
Note how we use this to access the object instance.
Now we can instantiate a new object from the class, passing a string, and
when we call hello, we'll get a personalized message:
When the object is initialized, the constructor method is called, with any
parameters passed.
Normally methods are defined on the object instance, not on the class.
You can define a method as static to allow it to be executed on the class instead:
class Person {
static genericHello() { return 'Hello'
}
}
Person.genericHello() //Hello
pg. 52
Inheritance
A class can extend another class, and objects initialized using that class
inherit all the methods of both classes.
Now if we instantiate a new object with class Programmer, it has access to the
hello() method:
Inside a child class, you can reference the parent class calling super():
pg. 53
The above program prints Hello, I am a Person. I am also a programmer...
pg. 54
Asynchronous Programming and
Callbacks
Most of the time, JavaScript code is ran synchronously.
This means that a line of code is executed, then the next one is executed, and
so on.
However, there are times when you cannot just wait for a line of code to
execute.
You can't just wait 2 seconds for a big file to load, and halt the program
completely.
You can't just wait for a network resource to be downloaded, before doing
something else.
One of the simplest examples of how to use callbacks is timers. Timers are not
part of JavaScript, but they are provided by the browser, and Node.js. Let me
talk about one of the timers we have: setTimeout().
Example:
setTimeout(() => {
// runs after 2 seconds console.log('inside the function')
}, 2000)
pg. 55
The function containing the console.log('inside the function') line will be executed after 2
seconds.
console.log('before')
setTimeout(() => {
// runs after 2 seconds console.log('inside the function')
}, 2000)
console.log('after')
before
after
inside the function
This is a very common pattern when working with the file system, the network,
events, or the DOM in the browser.
All the things I mentioned are not "core" JavaScript, so they are not explained
in this handbook, but you'll find lots of examples in Flavio’s handbooks
available at https://flavioscopes.com.
When the code is ready to invoke the callback, we invoke it passing the result:
pg. 56
}
pg. 57
Promises
Promises are an alternative way to deal with asynchronous code.
Like this:
When the doSomething() code ends, it calls the function received as a a parameter:
The main problem with this approach is that if we need to use the result of this
function in the rest of our code, all our code must be nested inside the
callback, and if we must do 2-3 callbacks, we enter in what is usually defined
"callback hell" with many levels of functions indented into other functions:
pg. 58
Promises are one way to deal with this.
Instead of doing:
doSomething()
.then(result => {
console.log(result)
})
We first call the function, then we have a then() method that is called when the
function ends.
The indentation does not matter, but you'll often use this style for clarity.
doSomething()
.then(result => {
console.log(result)
})
.catch(error => {
console.log(error)
})
pg. 59
We declare it as a promise object:
})
})
Rejecting a promise means ending it with an error (which results in calling the
catch() method in who uses it).
Here's how:
pg. 60
We can pass a parameter to the resolve and reject functions; of any type we
want.
pg. 61
Async and Await
Async functions are a higher-level abstraction over promises.
Any code that wants to use this function will use the async keyword right
before the function:
and doing so, any data returned by the promise is going to be assigned to the
data variable.
With one particular caveat: whenever we use the await keyword, we must do
so inside a function defined as async.
Like this:
The Async/await duo allows us to have a cleaner code and a simple mental
model to work with asynchronous code.
pg. 62
As you can see in the example above, our code looks very simple. Compare it
to code using promises, or callback functions.
And this is a very simple example, the major benefits will arise when the code
is much more complex.
As an example, here's how you would get a JSON resource using the Fetch
API, and parse it, using promises:
getFirstUserData()
pg. 63
getFirstUserData()
pg. 64
Variables scope
When I introduced variables, I talked about using const, let, and var. Scope is the
A variable defined as var inside a function is only visible inside that function.
Similarly, to a function argument:
A variable defined as const or let on the other hand is only visible inside the
block where it is defined.
A block is a set of instructions grouped into a pair of curly braces, like the ones
we can find inside an if statement or a for loop. And a function, too.
It's important to understand that a block does not define a new scope for var,
but it does for let and const.
If you call this function, you'll get some data printed to the console.
pg. 65
If you try to move console.log(data) after the if, it still works:
This is because var is function scoped, and there's a special thing happening
here, called hoisting. In short, the var declaration is moved to the top of the
closest function by JavaScript, before it runs the code. This is what the
function looks like to JS, internally:
Therefore, you can also console.log(data) at the top of a function, even before it's
declared, and you'll get undefined as a value for that variable:
function getData() {
console.log(data)
pg. 66
if (true) {
var data = 'some data'
}
}
but if you switch to let, you'll get an error ReferenceError: data is not
defined, because hoisting does not happen to let declarations.
It can be tricky at first, but once you realize this difference, then you'll see why
var is considered a bad practice nowadays compared to let: they do have fewer
moving parts, and their scope is limited to the block, which also makes them
very good as loop variables, because they cease to exist after a loop has
ended:
function doLoop() {
for (var i = 0; i < 10; i++) { console.log(i)
}
console.log(i)
}
doLoop()
When you exit the loop, i will be a valid variable with value 10.
pg. 67
Conclusion
Thanks a lot for reading this book.
Bye!
pg. 68