Vanilla JavaScript Fundamentals Part 1

Abbreviations
*[CSS]: Cascading Style Sheet
*[HTML]: Hypertext Markup Language
*[JS]: JavaScript
Let’s dive right in to JavaScript!
Learning Outcomes
How do you declare a variable?
What are three different ways to declare a variable?
Which one should you use when?
What are the rules for naming variables?
What are operators, operands, and operations?
What is concatenation and what happens when you add numbers and strings together?
What are the different types of operators in JavaScript?
What is the difference between
==
and===
?What are operator precedence values?
What are the increment/decrement operators?
What is the difference between prefixing and post-fixing them?
What are assignment operators?
What is the “Unary +” Operator?
How to Run JavaScript Code
All JavaScript we will be writing in the majority of the Foundations course will be run via the browser. Later lessons in Foundations and the NodeJS path will show you how to run JavaScript outside of the browser environment. Outside of these lessons, for now you should always default to running your JavaScript in the browser unless otherwise specified, otherwise you may run into unexpected errors.
The simplest way to get started is to simply create an HTML file with the JavaScript code inside of it. Type the basic HTML skeleton into a file on your computer somewhere:
Save and open this file up in a web browser (you can use Live Server to do this!) and then open up the browser’s console by right-clicking on the blank webpage and selecting “Inspect” or “Inspect Element”. In the ‘Developer Tools’ pane find and select the ‘Console’ tab, where you should see the output of our console.log statement.
Another way to include JavaScript in a webpage is through an external script. This is very similar to linking external CSS docs to your website.
JavaScript files have the extension .js
similar to .css
for stylesheets. External JavaScript files are used for more complex scripts.
Variables
You can think of variables as simply “storage containers” for data in your code. Until recently there was only one way to create a variable in JavaScript — the var statement. But in the newest JavaScript versions we have two more ways — let and const.
This variable tutorial will explain to you everything you need to know! Be sure to do the Tasks at the end. Information won’t stick without practice!
The above tutorial mentioned this, but it’s important enough to note again: let and const are both relatively new ways to declare variables in JavaScript. In many tutorials (and code) across the internet you’re likely to encounter var statements. Don’t let it bother you! There’s nothing inherently wrong with var, and in most cases var and let behave the same way. But sometimes the behavior of var is not what you would expect. Just stick to let (and const) for now. The precise differences between var and let will be explained later.
A variable is a "named storage" for data. The statement below creates (in other words, declares) a variable witt the name "message":
Now we can put some data into it by using the assignment operator =
:
The string is now saved into the memory area associated with the variable. We can access it using the variable name:
To be more concise, we can combine the variable declaration and assignment into a single line:
We can also declare multiple variables in one line:
The above is not recommended though due to harder readability, best to keep each declaration to its own line
A variable should be declared only once. A repeated declaration of the same variable is an error:
Variable naming
There are two limitations on variable names in JavaScript:
The name must contain only letters, digits, or the symbols '$' and '_'.
The first character must not be a digit.
Examples of valid names:
let userName;
let test123;
When the name contains multiple words, camelCase is commonly used. Ex: myVeryLongName
The dollar sign '$' and the underscore '_' can also be used in names.
Technically, there is no error here. Such names are allowed, but there is an international convention to use English in variable names. Even if we’re writing a small script, it may have a long life ahead. People from other countries may need to read it some time.
Name Things Right
Talking about variables, there’s one more extremely important thing.
A variable name should have a clean, obvious meaning, describing the data that it stores.
Variable naming is one of the most important and complex skills in programming. A quick glance at variable names can reveal which code was written by a beginner versus an experienced developer.
Please spend time thinking about the right name for a variable before declaring it. Doing so will repay you handsomely.
Some good-to-follow rules are:
Use human-readable names like userName or shoppingCart.
Stay away from abbreviations or short names like a, b, c, unless you really know what you’re doing.
Make names maximally descriptive and concise. Examples of bad names are data and value. Such names say nothing. It’s only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing.
Agree on terms within your team and in your own mind. If a site visitor is called a “user” then we should name related variables currentUser or newUser instead of currentVisitor or newManInTown.
Numbers
Numbers are the building blocks of programming logic! In fact, it’s hard to think of any useful programming task that doesn’t involve at least a little basic math… so knowing how numbers work is obviously quite important. Luckily, it’s also fairly straightforward.
This W3Schools lesson followed by this one, are good introductions to what you can accomplish with numbers in JavaScript.
This MDN article covers the same info from a slightly different point of view, while also teaching you how to apply some basic math in JavaScript. There’s much more that you can do with numbers, but this is all you need at the moment.
Read through (and code along with!) this article about operators in Javascript. Don’t forget to do the “Tasks” at the bottom of the page! It will give you a pretty good idea of what you can accomplish with numbers (among other things!) in JavaScript.
Terms: "unary", "binary", "operand"
- operand
is what operators are applied to
For instance, in the multiplication of 5 * 2 there are two operands: the left operand is 5 and the right operand is
Sometimes, people call these “arguments” instead of “operands”.
- unary
it has a single operand
the unary negation
-
reverses the sign of a number
- binary
it has to operands
The same minus exists in binary form as well:
String concatenation with binary +
Let’s meet features of JavaScript operators that are beyond school arithmetics.
Usually, the plus operator +
sums numbers.
But, if the binary +
is applied to strings, it merges (concatenates) them:
Note that if any of the operands is a string, then the other one is converted to a string too.
For example:
See, it doesn’t matter whether the first operand is a string or the second one.
Here's a more complex example:
Here, operators work one after another. The first +
sums two numbers, so it returns 4, then the next +
adds the string 1 to it, so it’s like 4 + '1' = '41'
.
Here, the first operand is a string, the compiler treats the other two operands as strings too. The 2 gets concatenated to '1', so it’s like '1' + 2 = "12"
and "12" + 2 = "122"
.
The binary +
is the only operator that supports strings in such a way. Other arithmetic operators work only with numbers and always convert their operands to numbers.
Here’s the demo for subtraction and division:
Numeric conversion, unary +
The plus +
exists in two forms: the binary form that we used above and the unary form.
The unary plus or, in other words, the plus operator +
applied to a single value, doesn’t do anything to numbers. But if the operand is not a number, the unary plus converts it into a number.
For example:
It actually does the same thing as Number(...)
, but is shorter.
The need to convert strings to numbers arises very often. For example, if we are getting values from HTML form fields, they are usually strings. What if we want to sum them?
The binary plus would add them as strings:
If we want to treat them as numbers, we need to convert and then sum them:
From a mathematician’s standpoint, the abundance of pluses may seem strange. But from a programmer’s standpoint, there’s nothing special: unary pluses are applied first, they convert strings to numbers, and then the binary plus sums them up.
Why are unary pluses applied to values before the binary ones? As we’re going to see, that’s because of their higher precedence.
Assignment
Let’s note that an assignment =
is also an operator. It is listed in the precedence table with the very low priority of 2.
That’s why, when we assign a variable, like x = 2 * 2 + 1
, the calculations are done first and then the =
is evaluated, storing the result in x
.
Assignment = returns a value
The fact of =
being an operator, not a “magical” language construct has an interesting implication.
All operators in JavaScript return a value. That’s obvious for +
and -
, but also true for =
.
The call x = value
writes the value
into x
and then returns it.
Here’s a demo that uses an assignment as part of a more complex expression:
In the example above, the result of expression (a = b + 1)
is the value which was assigned to a
(that is 3
). It is then used for further evaluations.
Funny code, isn’t it? We should understand how it works, because sometimes we see it in JavaScript libraries.
Although, please don’t write the code like that. Such tricks definitely don’t make code clearer or readable.
Chaining assignments
Another interesting feature is the ability to chain assignments:
Chained assignments evaluate from right to left. First, the rightmost expression 2 + 2
is evaluated and then assigned to the variables on the left: c
, b
and a
. At the end, all the variables share a single value.
Once again, for the purposes of readability it’s better to split such code into few lines:
That’s easier to read, especially when eye-scanning the code fast.
Modify-in-place
We often need to apply an operator to a variable and store the new result in that same variable.
For example:
This notation can be shortened using the operators +=
and *=
:
Short “modify-and-assign” operators exist for all arithmetical and bitwise operators: /=
, -=
, etc.
Such operators have the same precedence as a normal assignment, so they run after most other calculations:
JavaScript Arithmetic Operators
Arithmetic operators perform arithmetic on numbers (literals or variables).
Operator | Description |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
** | Exponential (ES2016) |
/ | Division |
% | Modulus (Remainder) |
++ | Increment |
-- | Decrement |
Arithmetic Operations
A typical arithmetic operation operates on two numbers.
The two numbers can be literals:
or variables:
or expressions:
Operators and Operands
The numbers (in an arithmetic operation) are called operands.
The operation (to be performed between the two operands) is defined by an operator.
Operand | Operator | Operand |
---|---|---|
100 | + | 50 |
Adding
The addition operator (+) adds numbers:
Subtracting
The subtraction operator (-) subtracts numbers:
Multiplying
The multiplication operator (*) multiplies numbers:
Dividing
The division operator (/) divides numbers:
Remainder
The modulus operator (%) returns the division remainder:
Incrementing/Decrementing
Increasing or decreasing a number by one is among the most common numerical operations.
So, there are special operators for it:
The increment operator (++) increments a variable by 1:
The decrement operator (--) decrements a variable by 1:
The operators ++
and -
can be placed either before or after a variable.
When the operator goes after the variable, it is in “postfix form”:
counter++
.The “prefix form” is when the operator goes before the variable:
++counter
.
Both of these statements do the same thing: increase counter
by 1
.
Is there any difference? Yes, but we can only see it if we use the returned value of ++/--
.
Let’s clarify. As we know, all operators return a value. Increment/decrement is no exception. The prefix form returns the new value while the postfix form returns the old value (prior to increment/decrement).
To see the difference, here’s an example:
In the line (*)
, the prefix form ++counter
increments counter
and returns the new value, 2
. So, the alert
shows 2
.
Now, let’s use the postfix form:
In the line (*)
, the postfix form counter++
also increments counter
but returns the old value (prior to increment). So, the alert
shows 1
.
Bitwise Operators
Bitwise operators treat arguments as 32-bit integer numbers and work on the level of their binary representation.
These operators are not JavaScript-specific. They are supported in most programming languages.
The list of operators:
AND ( & )
OR ( | )
XOR ( ^ )
NOT ( ~ )
LEFT SHIFT ( << )
RIGHT SHIFT ( >> )
ZERO-FILL RIGHT SHIFT ( >>> )
These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won’t need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the Bitwise Operators chapter on MDN when a need arises.
Comma
The comma operator ,
is one of the rarest and most unusual operators. Sometimes, it’s used to write shorter code, so we need to know it in order to understand what’s going on.
The comma operator allows us to evaluate several expressions, dividing them with a comma ,
. Each of them is evaluated but only the result of the last one is returned.
For example:
Here, the first expression 1 + 2
is evaluated and its result is thrown away. Then, 3 + 4
is evaluated and returned as the result.
Why do we need an operator that throws away everything except the last expression?
Sometimes, people use it in more complex constructs to put several actions in one line.
For example:
Such tricks are used in many JavaScript frameworks. That’s why we’re mentioning them. But usually they don’t improve code readability so we should think well before using them.
Exponentiation
The exponentiation operator (**) raises the first operand to the power of the second operand:
x ** y produces the same result as Math.pow(x,y)
:
Operator Precedence
Operator precedence describes the order in which operations are performed in an arithmetic expression.
Is the result of example above the same as 150 * 3, or is it the same as 100 + 150?
Is the addition or the multiplication done first?
As in traditional school mathematics, the multiplication is done first.
Multiplication (*) and division (/) have higher precedence than addition (+) and subtraction (-).
And (as in school mathematics) the precedence can be changed by using parentheses:
When using parentheses, the operations inside the parentheses are computed first.
When many operations have the same precedence (like addition and subtraction), they are computed from left to right:
JavaScript Operator Precedence Values
Value | Operator | Description | Example | Associativity | ||
---|---|---|---|---|---|---|
19 | () | Express grouping | (3 + 4) | n/a | ||
18 | . | Member | person.name | left-to-right | ||
18 | [] | Member | person["name"] | left-to-right | ||
18 | () | Function call | myFunction() | left-to-right | ||
18 | ?. | Optional Chaining (ES2020) | obj.val?.prop | n/a | ||
18 | new | new (with argument list) | new ... (...) | n/a | ||
17 | new | new (without argument list) | new Date() | right-to-left | ||
16 | ++ | Postfix Increment | i++ | n/a | ||
16 | -- | Postfix Decrement | i-- | n/a | ||
15 | ++ | Prefix Increment | ++i | right-to-left | ||
15 | -- | Prefix Decrement | --i | right-to-left | ||
15 | ! | Logical NOT | !(x==y) | right-to-left | ||
15 | ~ | Bitwise NOT | ~(x==y) | right-to-left | ||
15 | typeof | Type | typeof x | right-to-left | ||
15 | + | Unary plus | +"10" | right-to-left | ||
15 | - | Unary negation | -10 | right-to-left | ||
15 | void | void (2 == '2') | right-to-left | |||
15 | delete | delete Employee.name | right-to-left | |||
15 | await | await expression | right-to-left | |||
14 | ** | Exponentiation (ES2016) | 10**2 | right-to-left | ||
13 | * | Multiplication | 10*5 | left-to-right | ||
13 | / | Division | 10/5 | left-to-right | ||
13 | % | Division Remainder | 10 % 5 | left-to-right | ||
12 | + | Addition | 10+5 | left-to-right | ||
12 | - | Subtraction | 10-5 | left-to-right | ||
11 | << | Bitwise Shift left | x<<2 | left-to-right | ||
11 | >> | Bitwise Shift right | x>>2 | left-to-right | ||
11 | >>> | Bitwise Shift right unsigned | x>>>2 | left-to-right | ||
10 | < | Less than | x < y | left-to-right | ||
10 | <= | Less than or equal | x <= y | left-to-right | ||
10 | > | Greater than | x > y | left-to-right | ||
10 | >= | Greater than or equal | x >= y | left-to-right | ||
10 | in | Property in Object (ES2016) | "PI" in Math | left-to-right | ||
10 | instanceof | Instance of Object (ES2016) | instanceof Array | left-to-right | ||
9 | == | Equal | x == y | left-to-right | ||
9 | === | Strict Equal | x === y | left-to-right | ||
9 | != | Unequal | x != y | left-to-right | ||
9 | !== | Strict Unequal | x !== y | left-to-right | ||
8 | & | Bitwise AND | x & y | left-to-right | ||
7 | ^ | Bitwise XOR | x ^ y | left-to-right | ||
6 | \ | Bitwise OR | x \ | y | left-to-right | |
5 | && | Logical AND | x && y | left-to-right | ||
4 | \ | \ | Logical OR | x || y | left-to-right | |
4 | ?? | Nullish Coalescing | x ?? y | left-to-right | ||
3 | ?: | Condition (ternary) | ? "Yes" : "No" | right-to-left | ||
2 | = | Assignment | x=y | right-to-left | ||
2 | += | Assignment | x+=y | right-to-left | ||
2 | /= | Assignment | x/=y | right-to-left | ||
2 | -= | Assignment | x-=y | right-to-left | ||
2 | *= | Assignment | x*=y | right-to-left | ||
2 | %= | Assignment | x%=y | right-to-left | ||
2 | <<= | Assignment | x<<=y | right-to-left | ||
2 | >>= | Assignment | x>>=y | right-to-left | ||
2 | >>>= | Assignment | x>>>=y | right-to-left | ||
2 | &= | Assignment | x&=y | right-to-left | ||
2 | ^= | Assignment | x ^= y | right-to-left | ||
2 | \ | = | Assignment | x \ | = y | right-to-left |
2 | yield | Pause Function (ES2016) | yield x | right-to-left | ||
1 | , | Comma | 5, 6 | left-to-right |