Some Javascript guide
Who is this guide for?
This guide is for those who do not know javascript and wish to learn the basics of it.
Objective
After this tutorial you should have rough understanding of how to use javascript and be able to use it to do very, very basic stuff.
What is used in the tutorial?
- Your preferred browser (I will be using chrome)
- Your preferred text editor (I recommend sublime text)
Terminology
- —
Why use Javascript?
Javascript, as of this writing, is very widely used. From making your webpages work, to making your server work, to making your javascript console program, it is probably the most hyped / in-thing a programmer can delve into right now. By learning the basics of javascript, you can attempt to learn javascript frameworks like react and vue.
Guide Start
The Browser
I will be using Google Chrome on macOS for this guide.
Learning via the Console
Open up chrome if it is not open yet and open a new tab.
Press cmd + option + i
for mac or ctrl + shift + i
for windows to open up the inspector.

Now head over to the console tab where we will do some javascript.

Clear any logs if any by pressing the 'Clear console' button

It is the bottom right button of the 4.
Now you will do a standard command whenever you learn a programming language. You will type console.log('Hello World!')
and then press enter
. You should see Hello World!
on the console.

What you just did was to get the console to log the string 'Hello World!' (string means text).
In Javascript ''
& ""
both represents string
. I prefer to use ''
because you need not hold onto shift to type single quotes unlike for ""
.
You also see there is another line that says undefined
, you can pretty much ignore that for now.
Now we shall try to log a number. Type console.log(1)
and press enter
. You should see that the number 1
appears.
Now try with console.log('1')
instead. You will see that 1
appears again but as black instead of the blue of the first 1
.

From this we can see that Javascript has a datatype for text (String) and a datatype for numbers (Number). To help further illustrate the difference between a string and a number in Javascript, we shall do a bit of math.
Enter console.log(1+1)
. You should see 2 if my math did not fail me.

Similarly you can do subtraction, multiplication, and division in Javascript. Try console.log(1-2)
, console.log(2*3)
, and console.log(1/20)
.

TIP
*
- multiply
/
- divide
Now try doing console.log('1' + '1')
.

Woah, what is this behaviour that we are seeing? Well to put simply, in the 1+1
scenario, Javascript recognises this as addition between 2 numbers, thus it will do the math and output the result which is 2
. However, in the '1' + '1'
scenario, Javascript recognises those 2 1
as strings due to ''
, thus Javascript does something called 'Concatenation'.
What I am trying to get at is that computers do not understand that the string '1'
is a actually a number 1
and that we would actually like to have done addition instead of concatenation. If you expected that in the '1' + '1'
scenario will result in 2
then you should now understand that it gave 11
instead of 2
due to how Javascript deals with different datatypes.
But then you may wonder about -
, *
, and /
between strings. Wellll, using +
between strings changes the operation to become 'Concatenation' but for -
, *
, and /
, there are no concepts of string 'minus / multiply / divide' string in Javascript, thus Javascript will forcefully convert the strings into numbers and attempt to do math.
Try console.log('0' - '3')
, console.log('4' * '100')
, console.log('200' / '3')
, and console.log('a' - 'b')
.

As you can see, Javascript converts the strings to become numbers and then do the math operations which worked except for the last scenario. Javascript is unable to convert 'a'
and 'b'
into numbers, thus returning NaN
(Not a Number) as the result.
TIP
You may have also noticed that there is a limit to how many decimal points it can show before it rounds for the last decimal place.
Variables
Now that we have some basic commands and operations down, let's move on to Variables. The simpliest way to describe variables is that they 'store' information. The somewhat more proper description is that variables point to the location in memory where the data is stored.
Either way let's start getting familiar with them. Enter let name = 'Your name here'
, then enter name
by itself.

As you can see from the image, the variable name
was assigned the value 'Your name'
and we were able to retrieve the value from it by simply entering the variable.
TIP
There is also another keyword for declaring variables which is var
instead of let
but I won't delve into the differences here.
What we just did was declaring a variable called name
then we assigned a value of 'Your name here'
to it. The declaration part was done by using the let
keyword. You can actually declare a variable without assigning a value to it, so the code would look like let name
, then you can assign it afterwards just by doing name = 'Your name here'
(without the let
as it has already been declared).
TIP
If you tried to declare the same variable again, you would see a error message saying it has already been declared.
Now let's do 2 variables by spliting up our name to first and last. Enter let firstName = 'Your first name here'
then let lastName = 'Your last name here'
. After that, enter console.log(firstName + lastName)
.

As you can see similarly to our +
operation previously, Javascript saw that the values of the 2 variables were strings, thus it went ahead and concatenated them. Your name is probably missing a space between let's fix that by typing console.log(firstName + ' ' + lastName)

Boolean
true
or false
is what booleans are all about literally. Booleans exists to facilitate checks in logic. To give some example, enter 2 * 3 == 6
.

As you can see from the result given, 2 times 3 is 6. The check is done by comparing the result of 2 * 3
against the specifiec check value 6
. This is done via the ==
operator.
We also have other operators to do different checks like !=
(not equal check), >
(more than check), >=
(more than or equal check), <
(less than check), <=
(less than or equal check).
Test them out like so:
let a = 10
let b = 20
a < b // true
a > b // false
a * 2 == b // true
a * 2 <= b // true
a * 2 >= b // true
let c = '10'
a == c // ?
a === b // ?
TIP
//
- For writing comments in Javascript. Will not be executed by Javascript.
For the last 2 cases, I would like you to try it yourself to see how Javascript deals with such comparison.
If you tried them, you would see that the ==
operator is not as 'strict' as the ===
operator. ==
is ok with different datatypes of supposed 'same value' whereas ===
will not consider different datatypes to be equal at all even if the have the 'same value'.
Math.random
Let's throw some randomness in to change it up a little. We will generate a number and then we will check if it is more than 5. First we need to learn how to use Math.random
. Enter Math.random()
and you should see a random decimal value that is 0 <= random decimal value < 1
.

But generating values that are between 0 and 1 will never get us a value more than 5, so let's increase the range by multiplying. Enter Math.random() * 10
. Now the range of value is from 0 to 9.999999999999999.

Now we can do some checks, enter Math.random() * 10 > 5
.

if
statements
Let's complicate this check a little with a new keyword if
.
if (Math.random() * 10 > 5) {
console.log('More than 5!')
}
From the code above, we can see how if
statements are used. Reading it like english would be something along the lines of 'If Math.random() times 10 gives a result that is more than 5, we will log in the console "More than 5!"'. You may not see it now but the if
statement is a powerful tool that allows programs behave differently depending on certain variables.
else
and else if
We can chain checks by using else
and else if
keywords like so:
let randomInt = Math.random() * 10
if (randomInt > 8) {
console.log('More than 8!')
} else if (randomInt > 5) {
console.log('More than 5!')
} else {
console.log('Less than or equal to 5!')
}
TIP
the {
}
brackets are necessary if we want more than 1 line of code for each checks.
Mini Exercise 1: Leap Year check
This exercise will require that you:
- Generate a random year between 0 to 9999
- Check if the random year is a leap year
- Log the year in the console if it is a leap year
Generating random integers instead of floats (decimals)
Up till now, we have been using Math.random
to generate numbers for us but it has always been giving us decimals, or floats in technical terms. For Mini Exercise 1, what we need are integers (no decimal points). Thus a simple way is to floor the values that come from Math.random
.
// get a random float
// multiply it by 10
// floor it to get random integers
Math.floor(Math.random() * 10)
Change the range to be 0 to 9999
Math.floor(Math.random() * 10000)
Checking leap years
A brief explanation on what a leap year is:
A leap year (also known as an intercalary year or bissextile year) is a calendar year containing one additional day (or, in the case of lunisolar calendars, a month) added to keep the calendar year synchronized with the astronomical or seasonal year. - Wikipedia
The algorithm as extracted from Wikipedia is:
- if (year is not divisible by 4) then (it is a common year)
- else if (year is not divisible by 100) then (it is a leap year)
- else if (year is not divisible by 400) then (it is a common year)
- else (it is a leap year)
As you can see, wikipedia puts the algorithm in a form of pseudo code. To check if a number is divisible by another number, we use the %
(modulus) operator. The %
operator gives the remainder after the division. With the remainder we can tell if the number is divisible when the remainder is 0. Thus we can check like so:
2016 % 4 == 0 // true
Now you have all the parts you need to finish the mini exercise.
Implementing Wikipedia's pseudo code
let randomYear = Math.floor(Math.random() * 10000)
if (randomYear % 4 != 0) {
// Not leap year
} else if (randomYear % 100 != 0) {
// Is leap year
console.log(randomYear)
} else if (randomYear % 400 != 0) {
// Not leap year
} else {
// Is leap year
console.log(randomYear)
}
How I would write the code
let randomYear = Math.floor(Math.random() * 10000)
if (randomYear % 4 == 0 && randomYear % 100 != 0 || randomYear % 400 == 0) {
console.log(randomYear)
}
Logical Operators
You see some new operators in "How I would write the code": &&
and ||
. These are called "Logical Operators" and they are used with boolean values normally.
&&
Returns true only if both booleans are true.
true | false | |
---|---|---|
true | true | false |
false | false | false |
||
Returns true if either of the booleans is true.
true | false | |
---|---|---|
true | true | true |
false | true | false |
Example of their usage:
let c = true
let d = false
// Without using variables
true || false // true
// Using variables
c && c // true
c && d // false
d && c // false
d && d // false
c || c // true
c || d // true
d || c // true
d || d // false
for
loops
Well, I would like to generate 10 random years and then check each of them but I am too lazy to write the code 10 times just to do that. This is where we utilise loop statements and the 1 we will be learning now is for
loop.
for (let i = 0; i < 10; i++) {
console.log(i)
}
// Output
/*
0
1
2
3
4
5
6
7
8
9
*/
Let's break down the for loop:
for (/* declare and initialise */; /* check */; /* increment */)
is the general outline (Note the;
as they seperate the different parts)let i = 0
creates a variable called 'i' with initial value of0
i < 10
is the check the loop will execute at the start of every iterationi++
increases i by 1 at the end of each iteration{ /* code to execute for each iteration */ }
The best way to understand for
loops is to utilise the debugger. I won't show you how to use the debugger yet but I will show u how for
loops work through it.
Flow:
- Declares variable
i
first - Assign
i
with value 0 - Check if
i
less than 10 0 < 10
istrue
, proceed to body- Log
i
in the console - Increase
i
by 1 - Repeat step 3 to 6 another 9 times
- When
i
eventually becomes10
,i < 10
will be false,for
loop breaks out
Hopefully you understand how for loops work now, at least the main parts.
We can also do a 'reverse' loop like so:
for (let i = 9; i >= 0; i--) {
console.log(i)
}
// Output
/*
9
8
7
6
5
4
3
2
1
0
*/
We can also print a grid like so:
let grid = ''
// nested for loops to print 5 rows of 10 '*'
for (let i = 0; i < 5; i++) {
// We use `j` for our inner `for` loop
for (let j = 0; j < 10; j++) {
grid += '*' // OR grid = grid + '*'
}
grid += '\n' // \n - new line
}
console.log(grid)
// Output
/*
**********
**********
**********
**********
**********
*/
We can also print a pyramid like so:
let pyramid = '\n'
let rows = 5
for (let i = 0; i < rows; i++) {
// spaces before the '*' for each row
for (let j = 0; j < rows - 1 - i; j++) {
pyramid += ' '
}
// the '*' pyramid
for (let j = 0; j < 1 + i*2; j++) {
pyramid += '*'
}
pyramid += '\n'
}
console.log(pyramid)
// Output
/*
*
***
*****
*******
*********
*/
for
loop into the leap year check
Incorporate Let's incorporate the for
loop into the leap year check we did:
- Generate a random year
- Check if it is a leap year, if so log it
- Repeat this 10 times
Updated leap year checking
for (let i = 0; i < 10; i++) {
let randomYear = Math.floor(Math.random() * 10000)
if (randomYear % 4 == 0 && randomYear % 100 != 0 || randomYear % 400 == 0) {
console.log(randomYear)
}
}
Array
What is an 'Array'?. If you look up the english dictionary, specifically 'dictionary.com', it basically means a group or an arrangement. In Javascript context, and generally most computing concepts, 'Array' refers to a list of items. So in a rough sense, array is a collection. 'Array' and 'List' both mean collections but these terms have different meanings depending on the programming language or context they are used in, but I digress. All you need to know is these 2 terms exists and they both generally mean the same thing but are different.
That aside, let's look at an array in action.
let numbers = [1, 2, 3, 4, 5, 6]
console.log(numbers)
// Output
// (6) [1, 2, 3, 4, 5, 6]
If you execute the above code, you will see that the array get printed out. The (6)
refers to the length of the array, then it shows the array itself.
We can also mix it up a little
let mixed = [1, 2, 3, 'four', 'five', 'six', true, false]
console.log(mixed)
// Output
// (8) [1, 2, 3, "four", "five", "six", true, false]
Javascript allows arrays to contain whatever, but you generally won't use mix arrays much (nearly never for me).
We can also create an empty array like so:
let a = []
But an empty array by itself is rather pointless, so let's add some items into it.
let a = []
a.push(1)
a.push(2)
a.push(3)
console.log(a)
// Output
// (3) [1, 2, 3]
As you can see, we have a push
function to help us add an item to the array.
TIP
Did you know that the log
in console.log()
is also a function?
You probably subconsciously know that push
adds the new item at the back of the array. What if we would like to add the new item at the front?
let a = []
a.unshift(1)
a.unshift(2)
a.unshift(3)
console.log(a)
// Output
// (3) [3, 2, 1]
What about adding an item in between rather than at the start or end.
let a = [1, 2, 3]
a.push(1)
console.log(a)
// Output
// (3) [1, 2, 3]
// let's add 4 in between 1 and 2
let a = [1, 2, 3]
a.splice(1, 0, 4) // (add at position `1`, remove 0 elements, item to add)
console.log(a)
// Output
// (4) [1, 4, 2, 3]
To clarify further, position 1
means this
array: [1, 2, 3]
positions: 0 1 2
What this means is the the 1st item is position (index) 0
, the 2nd item is index 1
, so on and so forth. This is known as zero-based index. In normal situations we usually label the first item to have a position of 1
but in programming, the first item is most commonly index 0
. I am not really sure why, but I am sure you can google about it and learn more.
So we just covered adding to an array, what about removing?
let a = [1, 2, 3, 4, 5, 6]
a.pop() // removes last item
console.log(a)
// (5) [1, 2, 3, 4, 5]
a.shift() // removes first item
console.log(a)
// (4) [2, 3, 4, 5]
a.splice(2, 1) // starting at index `2`, remove 1 element
console.log(a)
// (3) [2, 3, 5]
TIP
Want to know what input the splice
function needs? Check out this page. Or just google something like 'mdn splice' (which is what I did). If you are not sure what you are looking at, just read the main content and just know these stuff exists. I know that is a rather unsatisfying solution but the knowledge will eventually link up and you will understand.
Well I went over functions to remove items from an array rather briefly but you probably got it right?
Now that we can add and remove, what about getting the nth index element?
let a = [1, 2, 3, 4, 5, 6]
console.log(a[0]) // get 1st element and log it
// 1
console.log(a[2]) // get 3rd element
// 3
console.log(a[a.length - 1]) // get last element and log it (minus 1 due to starting from 0)
// 6
// a.length is as it implys, it gives the length of the array
Let's incorporate array in the pyramid printing just to see an example usage! Do take some time to digest this piece of code. Look at the video below to see it in action.
let pyramidSizes = [3, 1, 5, 0, 10]
for (let i = 0; i < pyramidSizes.length; i++) {
// Get the iteration's pyramid size
let pyramidSize = pyramidSizes[i]
let pyramid = ''
for (let j = 0; j < pyramidSize; j++) {
// spaces before the '*' for each row
for (let k = 0; k < pyramidSize - 1 - j; k++) {
pyramid += ' '
}
// the '*' pyramid
for (let k = 0; k < 1 + j*2; k++) {
pyramid += '*'
}
pyramid += '\n'
}
console.log(pyramid)
}
Mini Exercise 2: Reverse string
- Reverse a string. E.g. 'abc' to 'cba'
strings are essentially an array of characters. Javascript allows us to access a character using the []
operators.
Try this mini exercise before looking at my answer.
Mini Exercise 2 Answer
let toBeReversed = '1234567890abc'
let reversed = ''
for (let i = toBeReversed.length - 1; i >= 0; i--) {
reversed += toBeReversed[i]
}
console.log(reversed)
// cba0987654321
Mini Exercise 3: Ceasar Cipher
In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence. - Wikipedia
A simple illustration of this:
-Ceasar cipher with LEFT shift of 3-
Original string: A B C D E F
| | | | | |
| | | | | |
| | | | | |
Encrypted string: X Y Z A B C
-Ceasar cipher with RIGHT shift of 3-
Original string: A B C D E F
| | | | | |
| | | | | |
| | | | | |
Encrypted string: D E F G H I
This mini exercise will require you to:
- Implement Ceasar Cipher that only does RIGHT shift and only handle lowercase characters
- The cipher must be able to take in any integer (including negative)
Some test cases for you to check with:
1. Right shift 3 - 'the quick brown fox jumps over the lazy dog' -> 'wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj'
2. Right shift 10 - 'the quick brown fox jumps over the lazy dog' -> 'dro aesmu lbygx pyh tewzc yfob dro vkji nyq'
3. Right shift 3000 - 'the quick brown fox jumps over the lazy dog' -> 'dro aesmu lbygx pyh tewzc yfob dro vkji nyq'
Wondering how you can obtain the corresponding character based on nth shifts? Well before we can go into that. We need to learn about 'Character codes'.
Here is a table of character that I painstakingly built:
Character Code | Character |
---|---|
32 | [space] |
33 | ! |
34 | " |
35 | # |
36 | $ |
37 | % |
38 | & |
39 | ' |
40 | ( |
41 | ) |
42 | * |
43 | + |
44 | , |
45 | - |
46 | . |
47 | / |
48 | 0 |
49 | 1 |
50 | 2 |
51 | 3 |
52 | 4 |
53 | 5 |
54 | 6 |
55 | 7 |
56 | 8 |
57 | 9 |
58 | : |
59 | ; |
60 | < |
61 | = |
62 | > |
63 | ? |
64 | @ |
65 | A |
66 | B |
67 | C |
68 | D |
69 | E |
70 | F |
71 | G |
72 | H |
73 | I |
74 | J |
75 | K |
76 | L |
77 | M |
78 | N |
79 | O |
80 | P |
81 | Q |
82 | R |
83 | S |
84 | T |
85 | U |
86 | V |
87 | W |
88 | X |
89 | Y |
90 | Z |
91 | [ |
92 | \ |
93 | ] |
94 | ^ |
95 | _ |
96 | ` |
97 | a |
98 | b |
99 | c |
100 | d |
101 | e |
102 | f |
103 | g |
104 | h |
105 | i |
106 | j |
107 | k |
108 | l |
109 | m |
110 | n |
111 | o |
112 | p |
113 | q |
114 | r |
115 | s |
116 | t |
117 | u |
118 | v |
119 | w |
120 | x |
121 | y |
122 | z |
TIP
Wondering what is before 32 and what is after 122? Well go google it yourself!
With this knowledge that characters are actually represented by numbers, we can actually use Javascript to convert characters to number and vice versa. Thus providing us a possible way to implement ceasar cipher. Don't see how this helps? Read on.
Given a string (of only lowercase alphabets), we will be able to get their character codes, for example 'abc' will give 97, 98, 99
. If we want to do a right shift of 3, we can just add 3 to the numbers giving us 100, 101, 102
which then corresponds to 'def'. The functions that will help us are: charCodeAt
and fromCharCode
.
Example usage:
'a'.charCodeAt(0) // at index 0 of the string
// 97
String.fromCharCode(97)
// "a"
You see that the 2 functions are used from 2 different places. charCodeAt
is a function that exists on all strings whereas fromCharCode
is under the 'String' object (we will delve into objects soon). Which makes sense to separate it like so since fromCharCode
function existing in all strings would not make sense (Getting characters from a character code when the string already has the characters like so 'a'.fromCharCode(97)
? I think not).
With this knowledge, try to implement the ceasar cipher on your own.
Mini Exercise 3 Answer
let toBeCeasarCiphered = 'abcdefghijklmnopqrstuvwxyz'
let encryptedString = ''
let rightShift = 10
for (let i = 0; i < toBeCeasarCiphered.length; i++) {
let charCode = toBeCeasarCiphered.charCodeAt(i)
charCode += rightShift % 26 // for shifts bigger than 25
if (charCode > 122) {
charCode = charCode % 122 + 96 // for characters to wrap back to 'a'
}
encryptedString += String.fromCharCode(charCode)
}
console.log(encryptedString)
// defghijklmnopqrstuvwxyzabc
Functions
Time for you to learn how to create your own functions.
A function is essentially a group of code.
function a:
code a
code b
code c
Everytime we call function a
, code a
, code b
, code c
will be done.
Pros of functions:
- You get to reduce number of code written by reusing functions
- Allows of abstraction and small modules/compartments/parts of codes to be grouped thus making the system easier to understand / work with
Cons of functions:
- You need to write the function
- Intricate processes are hidden away thus you may not know how it works unless you delve into the function
Example of a function:
// Create a function
function logSomeStuff() {
console.log('a')
console.log('b')
console.log('c')
console.log(1 + 1)
}
// Use the function
logSomeStuff()
/* Output
a
b
c
2
*/
From the above code, you can see that the function
keyword is used to define/start a function. The name follows afterwards with the ()
. The ()
are for parameters, in this case there are none which is why it is empty. Following that is the body of the function encompassed by the {}
.
We can also get functions to return a value to us.
function randomDigit() {
return Math.floor(Math.random() * 10)
}
randomDigit()
// 4
TIP
Why randomDigit above gives 4: IEEE-vetted random number - RFC 1149.5
As you can see from our randomDigit
function, the random digit is returned to us via the return
keyword.
Let's go back to the 'Leap Year Check' we did previously (hopefully you still remember it). As we know functions are meant to group code together for reuse. In the 'Leap Year Check' scenario, we had to type out the code everytime we wanted to check a new random year. With functions, we can reduce the number of code we write.
leapYearCheck Function:
// year is the parameter of the leapYearCheck function
function leapYearCheck(year) {
// We are return a boolean on whether the given year is a leap year or not
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0
}
leapYearCheck(2016)
// true
leapYearCheck(2017)
// false
leapYearCheck(1800)
// false
leapYearCheck(1600)
// true
With this function we can make the checking of the random years easier (kinda).
function leapYearCheck(year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0
}
for (let i = 0; i < 10; i++) {
let randomYear = Math.floor(Math.random() * 10000)
if (leapYearCheck(randomYear)) {
console.log(randomYear)
}
}
Mini Exercise 4: Calculate Coin Change function
- Given an amount of money
- Return an array of coins
Coins that exists in our example: 1 cent, 5 cents, 10 cents, 20 cents, 50 cents, 1 dollar
This mini exercise will assume that we try to maximise the big coins as much as possible rather than just return all of them as 1 cent coins. So if we have to find $3 change in coins, the function will return [0, 0, 0, 0, 0, 3]
rather than [200, 0, 0, 0, 0, 0]
.
Some test cases for you to use:
coinChange(200)
// (6) [0, 0, 0, 0, 0, 2]
coinChange(350)
// (6) [0, 0, 0, 0, 1, 3]
coinChange(10)
// (6) [0, 0, 1, 0, 0, 0]
coinChange(5)
// (6) [0, 1, 0, 0, 0, 0]
coinChange(1287)
// (6) [2, 1, 1, 1, 1, 12]
Mini Exercise 4 Answer
// `amount` is in cents
function coinChange(amount) {
let oneDollars = Math.floor(amount / 100)
// We take the remainder for calculating number of 50 cents
amount %= 100 // same as amount = amount % 100
let fiftyCents = Math.floor(amount / 50)
amount %= 50
let twentyCents = Math.floor(amount / 20)
amount %= 20
let tenCents = Math.floor(amount / 10)
amount %= 10
let fiveCents = Math.floor(amount / 5)
amount %= 5
let oneCents = amount
return [oneCents, fiveCents, tenCents, twentyCents, fiftyCents, oneDollars]
}
TIP
Did you manage to do this exercise? I hope you did.
Did you do it roughly the same way I did it? If you didn't, I hope you understand my answer.
Object: What it is
You might want to skip this part and move on to Object: Using it as this part delves a bit too deep for beginners. If you choose to read this part, well, just know that you are probably missing some extra knowledge that allows me to explain object
.
We will now learn about objects. Actually we have been using objects this whole time. 'Almost everything in Javascript is an Object' - Someone. That phrase is true.
Let's use the typeof
keyword to see what some types there are
typeof(console)
// "object"
typeof([])
// "object"
typeof('')
// "string"
typeof(10)
// "number"
typeof(3.14159)
// "number"
typeof(console.log)
// "function"
That doesn't seem like almost everything is an object? Well, before I show you why almost everything is an object, we need to know about 'prototypical inheritance'. What is prototypical inheritance? Well, we need to understand the concept of 'inheritance' first.
Inheritance, in terms of programming, means something along the lines of
...inheritance enables new objects to take on the properties of existing objects...'
We can use an analogy with fruits to help better understand.
- Apple is a fruit.
- Orange is a fruit.
- Apple's 'parent' is a 'Fruit'.
- Orange's 'parent' is 'Fruit'.
- Apple and Orange are not the same despite having the same 'parent'.
- Apple is red while Orange is orange.
- However, Apple and Orange can be considered 'siblings'.
- If we were to introduce a new fruit, Pear, it would be a fruit with a green color.
- The similarities between Apple, Orange, and Pear is that they are all able to be grown and eaten.
- Thus, 'Fruits' are able to be grown and eaten.
- 'Is Growable' and 'Is Edible' are properties of 'Fruit'.
- When something is a child of 'Fruit', it inherits such properties and becomes 'Growable' and 'Edible'.
Similarly, in the case of console
, console
is an object
, which means it would have inherited properties of object
.
So what is object
? Let's create an object and take a look at it.
let someObject = {} // `{}` is an object
typeof(someObject)
// "object"
typeof({})
// "object"
// in the console type the following:
someObject.__proto__ // stands for prototype
You should see an object like this:
constructor
- the function used to 'construct' the object. In this case it is the function Object
(kinda confusing but note the case sensitivity).
toString
- a function that exists on all objects, this function converts the object into a string representation.
From the above image, we can see that someObject
's prototype is actually Object
's prototype. So what is prototype? It is a part of an object that contains properties to be 'inherited' by the object's child objects. Thus, from the above image, we can see that every object will have that exact 'prototype'.
Let's take a look at 'String'.
String's prototype chain:
''.__proto__
gives the 'String' prototype.
''.__proto__.__proto__
get the __proto__
's proto which is the 'Object' prototype.
Number's prototype chain:
let aNumber = 0
aNumber.__proto__
// Returns a 'Number' prototype
aNumber.__proto__.__proto__
// Returns the 'Number' prototype's prototype which is also the 'Object' prototype
Object: Using it
If you didn't read the above part or you read it but didn't understand, WELL, just know that objects hold data. Similar to an Array holding data, objects also hold data.
// Objects can be anything
let blankObject = {}
blankObject
// {}
let randomObject = {
name: 'Whatever', // note the comma
width: 10,
height: 20
}
randomObject.name
// "Whatever"
randomObject.width
// 10
randomObject.height
// 20
randomObject.name = 'some other name'
randomObject.name
// "some other name"
// We can add in a new property like so
randomObject.abc = 'def'
randomObject.abc
// "def"
randomObject
/*
{
abc: "def",
height: 20,
name: "some other name",
width: 10,
__proto__: Object
}
*/
// objects can hold anything
// including other objects
randomObject.innerObject = {}
randomObject.innerObject.a = 1
randomObject.innerObject.b = 'something'
randomObject
/*
{
abc: "def",
height: 20,
innerObject: { a: 1, b: 'something' },
name: "some other name",
width: 10,
__proto__: Object
}
*/
You get the idea that object
is literally whatever data you want to keep in it.
Let's use objects in the generation of the pyramid as an example.
// Convert the pyramid generator to a function for easy reuse
// rows - number of rows for the pyramid
// char - the character used to make the pyramid
function generatePyramid(rows, char) {
let pyramid = ''
for (let j = 0; j < rows; j++) {
// spaces before the '*' for each row
for (let k = 0; k < rows - 1 - j; k++) {
pyramid += ' '
}
// the '*' pyramid
for (let k = 0; k < 1 + j*2; k++) {
pyramid += char
}
pyramid += '\n'
}
// We return the pyramid string instead of console.log
return pyramid
}
// test the function
console.log(generatePyramid(5, '$'))
/*
$
$$$
$$$$$
$$$$$$$
$$$$$$$$$
*/
// I want to use an array of objects to generate a bunch of different pyramids
let pyramidSettings = [
{
rows: 5,
char: '$'
},
{
rows: 3,
char: '0'
},
{
rows: 8,
char: 'l'
}
]
for (let i = 0; i < pyramidSettings.length; i++) {
// Get the current iteration's pyramid setting
let pyramidSetting = pyramidSettings[i]
let pyramid = generatePyramid(pyramidSetting.rows, pyramidSetting.char)
console.log(pyramid)
}
/*
$
$$$
$$$$$
$$$$$$$
$$$$$$$$$
0
000
00000
l
lll
lllll
lllllll
lllllllll
lllllllllll
lllllllllllll
lllllllllllllll
*/
Mini Exercise 5: Filter and Sort People
Now we will be learning about filtering and sorting with Javascript. You know how when you google something, google is actually filtering away the irrelevant results and then sorting the remaining base on how relevant they are? We aren't going to do that crazily complex filter and sort, what we will do are the basics, naive way of filtering and sorting.
- You are given an Array of person object
- Person object contains:
- Name
- Gender
- Age
- You will create filter functions:
filterByName(people, query)
- The criteria is if the person's name contains the
query
- E.g.
query
is'o'
, the people who fit this criteria are:- J
o
hn - B
o
bby - Chl
o
e - ...
- J
- Google 'javascript string contains' and check out the answers in 'stackoverflow' to learn how to check if a string is in a string. OR Look at the answer below.
- The criteria is if the person's name contains the
filterByGender(people, gender)
filterByAge(people, fromAge, toAge)
- You will create sort functions:
sortByName(people, isAsc)
- Alphabetical order
- Ascending: aa, ab, ac, ad, bb, bc, bd
- Descending: bd, bc, bb, ad, ac, ab, aa
- Alphabetical order
sortByGender(people, isAsc)
- Alphabetical order
- Ascending: f, m
- Descending: m, f
- Alphabetical order
sortByAge(people, isAsc)
- Numerical order
- Ascending: 20, 23, 25, 30, 35
- Descending: 35, 30, 25, 23, 20
- Numerical order
- Your functions cannot change the original array
TIP
I have given you the function names and their expected parameters.
Note that you are suppose to pass the people array into the people
parameter.
query
- the string to filter name by
gender
- the string to filter gender by
fromAge
- the starting age (inclusive)
toAge
- the ending age (inclusive)
isAsc
- boolean for if it is ascending order or not (otherwise descending)
The people you will be working with
let people = [
{
name: 'John',
gender: 'm',
age: 30
},
{
name: 'Rick',
gender: 'm',
age: 23
},
{
name: 'Jessica',
gender: 'f',
age: 26
},
{
name: 'Bobby',
gender: 'm',
age: 45
},
{
name: 'Chloe',
gender: 'f',
age: 34
},
{
name: 'Kai',
gender: 'm',
age: 19
},
{
name: 'Hernandez',
gender: 'm',
age: 26
},
{
name: 'Mary',
gender: 'f',
age: 23
},
{
name: 'Pauline',
gender: 'f',
age: 50
},
]
TIP
for sorting arrays, you should use the sort
function
Filter Functions Guide
- Prepare an empty array to contain the people that meet the filter criteria
- Iterate (
for
loop) the people array - For each person in the the array, check if they meet the criteria
- If the person does meet the criteria, add them to the new array
- After iterating through the people array, return the filtered array
Sort Functions Guide
- You will need to make a 'copy' of the people array (google 'javascript make copy of array')
- Using the built in
sort
function, you can sort the copied array - return the sorted array
Mini Exercise 5 Answers
filterByName
function filterByName(people, query) {
let filteredPeople = []
for (let i = 0; i < people.length; i++) {
let person = people[i]
if (person.name.indexOf(query) > -1) { // OR .includes for ES6 // What is ES? go google 'javascript es6'
filteredPeople.push(person) // remember how to add to an array?
}
}
return filteredPeople
}
filterByName(people, 'o')
/*
(3) [{...}, {...}, {...}]
> 0: {name: "John", gender: "m", age: 30}
> 1: {name: "Bobby", gender: "m", age: 45}
> 2: {name: "Chloe", gender: "f", age: 34}
length: 3
>__proto__: Array(0)
*/
filterByGender
function filterByGender(people, gender) {
let filteredPeople = []
for (let i = 0; i < people.length; i++) {
let person = people[i]
if (person.gender == gender) {
filteredPeople.push(person)
}
}
return filteredPeople
}
filterByGender(people, 'm')
/*
(5) [{...}, {...}, {...}, {...}, {...}]
> 0: {name: "John", gender: "m", age: 30}
> 1: {name: "Rick", gender: "m", age: 23}
> 2: {name: "Bobby", gender: "m", age: 45}
> 3: {name: "Kai", gender: "m", age: 19}
> 4: {name: "Hernandez", gender: "m", age: 26}
length: 5
> __proto__: Array(0)
*/
filterByAge
function filterByAge(people, fromAge, toAge) {
let filteredPeople = []
for (let i = 0; i < people.length; i++) {
let person = people[i]
// Remember how to combine boolean expressions?
if (person.age >= fromAge && person.age <= toAge) {
filteredPeople.push(person)
}
}
return filteredPeople
}
filterByAge(people, 20, 30)
/*
(5) [{...}, {...}, {...}, {...}, {...}]
> 0: {name: "John", gender: "m", age: 30}
> 1: {name: "Rick", gender: "m", age: 23}
> 2: {name: "Jessica", gender: "f", age: 26}
> 3: {name: "Hernandez", gender: "m", age: 26}
> 4: {name: "Mary", gender: "f", age: 23}
length: 5
> __proto__: Array(0)
*/
sortByName
function sortByName(people, isAsc) {
let copiedPeople = people.slice()
if (isAsc) {
// Woah a function declaration in a function call in a function declaration?
// If you haven't already googled 'javascript array sort' and read up in
// mozzila developer network or some other similar website regarding this
// function... Maybe go google it and read up?
copiedPeople.sort(function (person1, person2) {
// Some strings can be 'more' than other strings
// Remember the character code? Character codes are numbers, so the string
// can be compared via the character codes
if (person1.name < person2.name) {
return -1
} else if (person1.name > person2.name) {
return 1
}
return 0
})
} else {
copiedPeople.sort(function (person1, person2) {
// swap the `1` and `-1`
if (person1.name < person2.name) {
return 1
} else if (person1.name > person2.name) {
return -1
}
return 0
})
}
return copiedPeople
}
sortByName(people, true)
/*
(9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
> 0: {name: "Bobby", gender: "m", age: 45}
> 1: {name: "Chloe", gender: "f", age: 34}
> 2: {name: "Hernandez", gender: "m", age: 26}
> 3: {name: "Jessica", gender: "f", age: 26}
> 4: {name: "John", gender: "m", age: 30}
> 5: {name: "Kai", gender: "m", age: 19}
> 6: {name: "Mary", gender: "f", age: 23}
> 7: {name: "Pauline", gender: "f", age: 50}
> 8: {name: "Rick", gender: "m", age: 23}
length: 9
> __proto__: Array(0)
*/
sortByGender
function sortByGender(people, isAsc) {
let copiedPeople = people.slice()
if (isAsc) {
copiedPeople.sort(function (person1, person2) {
if (person1.gender < person2.gender) {
return -1
} else if (person1.gender > person2.gender) {
return 1
}
return 0
})
} else {
copiedPeople.sort(function (person1, person2) {
// swap the `1` and `-1`
if (person1.gender < person2.gender) {
return 1
} else if (person1.gender > person2.gender) {
return -1
}
return 0
})
}
return copiedPeople
}
sortByGender(people, true)
/*
(9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
> 0: {name: "Jessica", gender: "f", age: 26}
> 1: {name: "Chloe", gender: "f", age: 34}
> 2: {name: "Mary", gender: "f", age: 23}
> 3: {name: "Pauline", gender: "f", age: 50}
> 4: {name: "John", gender: "m", age: 30}
> 5: {name: "Rick", gender: "m", age: 23}
> 6: {name: "Bobby", gender: "m", age: 45}
> 7: {name: "Kai", gender: "m", age: 19}
> 8: {name: "Hernandez", gender: "m", age: 26}
length: 9
> __proto__: Array(0)
*/
sortByAge
function sortByAge(people, isAsc) {
let copiedPeople = people.slice()
if (isAsc) {
copiedPeople.sort(function (person1, person2) {
return person1.age - person2.age
})
} else {
copiedPeople.sort(function (person1, person2) {
return person2.age - person1.age
})
}
return copiedPeople
}
sortByAge(people, false)
/*
(9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
> 0: {name: "Pauline", gender: "f", age: 50}
> 1: {name: "Bobby", gender: "m", age: 45}
> 2: {name: "Chloe", gender: "f", age: 34}
> 3: {name: "John", gender: "m", age: 30}
> 4: {name: "Jessica", gender: "f", age: 26}
> 5: {name: "Hernandez", gender: "m", age: 26}
> 6: {name: "Rick", gender: "m", age: 23}
> 7: {name: "Mary", gender: "f", age: 23}
> 8: {name: "Kai", gender: "m", age: 19}
length: 9
> __proto__: Array(0)
*/