Introduction to JavaScript
The first front-end web technology we will learn is JavaScript. JavaScript (often shortened to JS) is a lightweight, interpreted or JIT (i.e., Just In Time) compiled language meant to be embedded in host environments, for example, web browsers.
JavaScript looks similar to C/C++ or Java in some of its syntax, but is quite different in philosophy; it is more closely related to Scheme than C. For example, JavaScript is a dynamic scripting language supporting multiple programming styles, from object-oriented to imperative to functional.
JavaScript is one of, if not the most popular programming languages in the world, and has been for many years. Learning JavaScript well will be a tremendous asset to any software developer, since so much of the software we use is built using JS.
JavaScript's many versions: JavaScript is an evolving language, and you'll hear it referred to by a number of names, including: ECMAScript (or ES), ES5, ES6, ES2015, ES2017, ..., ES2021, ES2022, etc. ECMA is the European Computer Manufacturers Association, which is the standards body responsible for the JS language. As the standard evolves, the specification goes through different versions, adding or changing features and syntax. In this course we will primarily focus on ECMAScript 6 (ES6) and newer versions, which all browsers support. We will also sometimes use new features of the language, which most browsers support. Language feature support across browsers is maintained in this table.
JavaScript Resources
Throughout the coming weeks, we'll make use of a number of important online resources. They are listed here so you can make yourself aware of them, and begin to explore on your own. All programmers, no matter how experienced, have to return to these documents on a routine basis, so it's good to know about them.
JavaScript Environments
Unlike C, which is compiled to machine code, JavaScript is meant to be run within a host environment. There are many possible environments, but we will focus on the following:
- Web Browsers, and their associated developer tools, primarily:
- node.js, and its command line REPL (Read-Eval-Print-Loop)
If you haven't done so already, you should install all of the above.
JavaScript Engines
JavaScript is parsed, executed, and managed (i.e., memory, garbage collection, etc) by an engine written in C/C++. There are a number of JavaScript engines available, the most common of which are:
- V8, maintained an used by Google in Chrome and in node.js
- SpiderMonkey, maintained and used by Mozilla in Firefox
- ChakraCore, maintained and used by Microsoft in Edge
- JavaScriptCore, maintained and used by Apple in Safari
These engines, much like car engines, are meant to be used within a larger context. We will encounter them indirectly via web browsers and in node.js.
It's not important to understand a lot about each of these engines at this point, other than to be aware that each has its own implementation of the ECMAScript standards, its own performance characteristics (i.e., some are faster at certain things), as well as its own set of bugs.
Running JavaScript Programs
JavaScript statements can be stored in an external file with a .js file extension,
or embedded within HTML code via the HTML <script> element. As a developer, you also
have a number of options for writing and executing JavaScript statements or files:
-
From the command line via node.js. You'll learn more about node.js in subsequent courses, but we'll also use it sometimes in this course to quickly try test JavaScript expressions, and to run JavaScript programs outside the browser.
-
Using Firefox's Developer Tools, and in particular the Web Console, JavaScript Debugger, and Scratchpad.
-
Using Chrome's DevTools, and in particular the Console and Sources Debugger
-
Finally, we'll eventually write JavaScript that connects with HTML and CSS to create dynamic web pages and applications.
Take some time to install and familiarize yourself with all of the methods listed above.
JavaScript Syntax
Recommend Readings
We will spend a month learning JavaScript, and there is no one best way to do it. The more you read and experiment the better. The following chapters/pages give a good overview:
- Chapter 1. Basic JavaScript of Exploring JS (ES5).
- MDN JavaScript Introduction Tutorial
- Chapter 1. Values, Types and Operators and Chapter 2. Program Structure of Eloquent JavaScript (2nd Ed.).
Important Ideas
-
Like C, JavaScript is Case-Sensitive:
customerCountis not the same thing asCustomerCountorcustomercount -
Name things using
camelCase(first letter lowercase, subsequent words start with uppercase) vs.snake_case. -
Semicolons are optional in JavaScript, but highly recommended. We'll expect you to use them in this course, and using them will make working in C++, Java, CSS, etc. much easier, since you have to use them there.
-
Comments work like C/C++, and can be single or multi-line
// This is a single line comment. NOTE: the space between the // and first letter.
/*
This is a multi-line comment,
and can be as long as you need.
*/
- Whitespace: JavaScript will mostly ignore whitespace (spaces, tabs, newlines). In this course we will expect you to use good indentation practices, and for your code to be clean and readable. Many web programmers use Prettier to automatically format their code, and we will too:
// This is poorly indented, and needs more whitespace
function add(a, b) {
if (!b) {
return a;
} else {
return a + b;
}
}
// This is much more readable due to the use of whitespace
function add(a, b) {
if (!b) {
return a;
} else {
return a + b;
}
}
-
JavaScript statements: a JavaScript program typically consists of a series of statements. A statement is a single-line of instruction made up of objects, expressions, variables, and events/event handlers.
-
Block statement: a block statement, or compound statement, is a group of statements that are treated as a single entity and are grouped within curly brackets
{...}. Opening and closing braces need to work in pairs. For example, if you use the left brace{to indicate the start of a block, then you must use the right brace}to end it. The same matching pairs applies to single'......'and double"......."quotes to designate text strings. -
Functions are one of the primary building blocks of JavaScript. A function defines a subprogram that can be called by other parts of your code. JavaScript treats functions like other built-in types, and they can be stored in variables passed to functions, returned from functions or generated at run-time. Learning how to write code in terms of functions will be one of your primary goals as you get used to JavaScript.
-
Variables are declared using the
letkeyword. You must use theletkeyword to precede a variable name, but you do not need to provide a type, since the initial value will set the type.
JavaScript version note: JavaScript also supports the
varandconstkeywords for variable declaration. We will primarily useletin this course, but be aware ofvarandconstas well, which other developers will use.
let year;
let seasonName = 'Fall';
// Referring to and using syntax:
year = 2023;
console.log(seasonName, year);
- JavaScript Variables: variables must start with a letter (
a-zA-z), underscore (_), or dollar sign ($). They cannot be a reserved (key) word. Subsequent characters can be letters, numbers, underscores.
NOTE: If you forget to use the let keyword, JavaScript will still allow you to use a variable, and simply create a global variable. We often refer to this as "leaking a global," and it should always be avoided:
let a = 6; // GOOD: a is declared with let
b = 7; // BAD: b is used without declaration, and is now a global
- Data Types: JavaScript is a typeless language--you don't need to specify a type for your data (it will be inferred at runtime). However, internally, the following data types are used:
Number- a double-precision 64-bit floating point number. UsingNumberyou can work with both Integers and Floats. There are also some specialNumbertypes,InfinityandNaN.BigInt- a value that can be too large to be represented by aNumber(larger thanNumber. MAX_SAFE_INTEGER,) can be represented by aBigInt. This can easily be done by appendingnto the end of an integer value.String- a sequence of Unicode characters. JavaScript supports both single ('...') and double ("...") quotes when defining aString.Boolean- a value oftrueorfalse. We'll also see how JavaScript supports so-called truthy and falsy values that are not pureBooleans.Object, which includesFunction,Array,Date, and many more. - JavaScript supports object-oriented programming, and uses objects and functions as first-class members of the language.Symbol- a primitive type in JavaScript that represents a unique and anonymous value/identifier. They can normally be used as an object's unique properties.null- a value that means "this is intentionally nothing" vs.undefinedundefined- a special value that indicates a value has never been defined.
| Declaration | Type | Value |
|---|---|---|
let s1 = "some text"; | String | "some text" |
let s2 = 'some text'; | String | "some text" |
let s3 = '172'; | String | "172" |
let s4 = '172' + 4; | String | "1724" (concatenation vs. addition) |
let n1 = 172; | Number | 172 (integer) |
let n2 = 172.45; | Number | 172.45 (double-precision float) |
let n3 = 9007199254740993n; | BigInt | 9007199254740993n (integer) |
let b1 = true; | Boolean | true |
let b2 = false; | Boolean | false |
let b3 = !b2; | Boolean | true |
let s = Symbol("Sym"); | symbol | Symbol(Sym) |
let c; | undefined | undefined |
let d = null; | object | null |
Consider a simple program from your C course, and how it would look in JavaScript
// Area of a Circle, based on https://scs.senecac.on.ca/~btp100/pages/content/input.html
// area.c
#include <stdio.h> // for printf
int main(void)
{
const float pi = 3.14159f; // pi is a constant float
float radius = 4.2; // radius is a float
float area; // area is a float
area = pi * radius * radius; // calculate area from radius
printf("Area = %f\n", area); // copy area to standard output
return 0;
}
Now the same program in JavaScript:
const pi = 3.14159; // pi is a Number
let radius = 4.2; // radius is a Number
let area; // area is (currently) undefined
area = pi * radius * radius; // calculate area from radius
console.log('Area = ' + area); // print area to the console
We could also have written it like this, using Math.PI, which we'll learn about later:
let radius = 4.2; // radius is a Number
let area = Math.PI * radius * radius; // calculate area from radius
console.log('Area', area); // print area to the console
- Common JavaScript Operators (there are more, but these are a good start):
| Operator | Operation | Example |
|---|---|---|
+ | Addition of Numbers | 3 + 4 |
+ | Concatenation of Strings | "Hello " + "World" |
- | Subtraction of Numbers | x - y |
* | Multiplication of Numbers | 3 * n |
/ | Division of Numbers | 2 / 4 |
% | Modulo | 7 % 3 (gives 1 remainder) |
++ | Post/Pre Increment | x++, ++x |
-- | Post/Pre Decrement | x--, --x |
= | Assignment | a = 6 |
+= | Assignment with addition | a += 7 same as a = a + 7. Can be used to join Strings too |
-= | Assignment with subtraction | a -= 7 same as a = a - 7 |
*= | Assignment with multiplication | a *= 7 same as a = a * 7 |
/= | Assignment with division | a /= 7 same as a = a / 7 |
&& | Logical AND | if(x > 3 && x < 10) both must be true |
() | Call/Create | () invokes a function, f() means invoke/call function stored in variable f |
|| | Logical OR | if(x === 3 || x === 10) only one must be true |
| | Bitwise OR | 3.1345|0 gives 3 as an integer |
! | Logical NOT | if(!(x === 2)) negates an expression |
== | Equal | 1 == 1 but also 1 == "1" due to type coercion |
=== | Strict Equal | 1 === 1 but 1 === "1" is not true due to types. Prefer === |
!= | Not Equal | 1 != 2, with type coercion |
!== | Strict Not Equal | 1 !== "1". Prefer !== |
> | Greater Than | 7 > 3 |
>= | Greater Than Or Equal | 7 >=7 and 7 >= 3 |
< | Less Than | 3 < 10 |
<= | Less Than Or Equal | 3 < 10 and 3 <=3 |
typeof | Type Of | typeof "Hello" gives 'string', typeof 6 gives 'number' |
cond ? a : b | Ternary | status = (age >= 18) ? 'adult' : 'minor'; |
JavaScript version note: you may encounter
=>in JavaScript code, which looks very similar to<=or>=. If you see=>it is an arrow function, which is new ES6 syntax for declaring a function expression. We will slowly introduce this syntax, especially in later courses.
- JavaScript is dynamic, and variables can change value and type at runtime:
let a; // undefined
a = 6; // 6, Number
a++; // 7, Number
a--; // 6, Number
a += 3; // 9, Number
a = 'Value=' + a; // "Value=9", String
a = !!a; // true, Boolean
a = null; // null
-
JavaScript is a garbage collected language. Unlike C, memory automatically gets freed at runtime when variables are not longer in scope or reachable. We still need to be careful not to leak memory (i.e., hold onto data longer than necessary, or forever) and block the garbage collector from doing its job.
-
Strings: JavaScript doesn't distinguish between a single
charand a multi-characterString--everything is aString. You define aStringusing either single ('...'), double ("...") quotes. Try to pick one style and stick with it within a given file/program vs. mixing them. -
JavaScript version note: newer versions of ECMAScript also allow for the use of template literals. Instead of
'or", a template literal uses ` (backticks), and you can also interpolate expressions. -
A JavaScript expression is any code (e.g., literals, variables, operators, and expressions) that evaluates to a single value. The value may be a
Number,String, anObject, or a logical value.
let a = 10 / 2; // arithmetic expression
let b = !(10 / 2); // logical expression evaluates to false
let c = '10 ' + '/' + ' 2'; // string, evaluates to "10 / 2"
let f = function () {
return 10 / 2;
}; // function expression, f can now be called via the () operator
let d = f(); // f() evaluates to 10/2, or the Number 5
- JavaScript execution flow is determined using the following four (4) basic control structures:
- Sequential: an instruction is executed when the previous one is finished.
- Conditional: a logical condition is used to determine which instruction will be executed next - similar to the
ifandswitchstatements in C (which JavaScript also has). - Looping: a series of instructions are repeatedly executed until some condition is satisfied - similar to the
forandwhilestatements in C (which JavaScript also has). There are many different types of loops in JavaScript: for exampleforloops andwhileloops, as well as ways tobreakout of loops or skip iterations withcontinue. We'll cover other types as we learn aboutObjectandArray. - Transfer: jump to, or invoke a different part of the code - similar to calling a function in C.
/**
* 1. Sequence example: each statement is executed one after the other
**/
let a = 3;
let b = 6;
let c = a + b;
/**
* 2. Conditional examples: a decision is made based on the evaluation of an expression,
* and a code path (or branch) taken.
**/
let grade;
let mark = 86;
if (mark >= 90) {
grade = 'A+';
} else if (mark >= 80) {
grade = 'A';
} else if (mark >= 70) {
grade = 'B';
} else if (mark >= 60) {
grade = 'C';
} else if (mark >= 50) {
grade = 'D';
} else {
grade = 'F';
}
switch (grade) {
case 'A+':
// do these steps if grade is A+
break;
case 'A':
// do these steps if grade is A
break;
case 'B':
// do these steps if grade is B
break;
case 'C':
// do these steps if grade is C
break;
case 'D':
// do these steps if grade is D
break;
default:
// do these steps in any other case
break;
}
/**
* 3. Looping example: a set of statements are repeated
**/
let total = 0;
for (let i = 1; i < 11; i++) {
total += i;
console.log('i', i, 'total', total);
}
/**
* 4. Transfer example: a set of statements are repeated
**/
function add(a, b) {
// declaring the add function
if (!b) {
// check if the b argument exists/has a value
return a; // if not, simply return the value of argument a
}
return a + b; // otherwise, return the two arguments added together
}
let total;
total = add(56); // invoking the add function with a single argument
total = add(total, 92); // invoking the add function with two arguments