let x = "Hello"; // x is a string
x = 10; // x becomes a number
y = "5"; // y is string, global variable (not preferred)
let z = x + y; // converts x to a string and performs addition
// z is a string "105"
This course focuses on frontend only, whereas COMP.CS.500 introduces the full stack
<button onclick="alert('Hello, world!')">Click me</button>
<script>
document.addEventListener("DOMContentLoaded", function() {
document.querySelector("p.greet").innerText = "Hello from on-page script!";
});
</script>
<script src="script.js"></script>
. . .
<link rel="stylesheet" href="css/js.css"/>
<body>
JWT
<script src="script.js"></script>
</body>
. . .
function greet() {
const elem = document.querySelector("p.greet");
const greetText = "";
const inHours = new Date().getHours(); // Added parentheses for function call
if (inHours > 21 || inHours < 1) {
greetText = 'Good night!';
} else if (inHours > 18) {
greetText = 'Good evening!';
} else if (inHours > 11) {
greetText = 'Good afternoon!';
} else if (inHours > 5) {
greetText = 'Good morning!';
} else {
greetText = 'You should be sleeping!'; // Corrected typo and added exclamation mark
}
if (elem) { // Added a check to make sure the element exists before trying to modify it
elem.innerHTML = greetText; // Corrected variable name: greetElem to elem
} else {
console.error("Greeting element not found!"); // Added error handling
}
}
greet();
...to ensure the DOM is constructed. This allows the script to access and manipulate elements without errors. Other mechanisms:
defer
: <script defer src="script.js"></script>
-
Defers script execution until after the HTML parsing is complete, but before the
DOMContentLoaded event.DOMContentLoaded
event. This ensures the script runs after the DOM is
ready. Example:
document.addEventListener('DOMContentLoaded', function() {
// Your code here
greet();
});
<link>
element:<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous">
<script>
element:<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
integrity
:crossorigin
:anonymous
: Fetches the resource without credentials (default).use-credentials
: Fetches the resource with credentials.Feature | var | let | const |
---|---|---|---|
Introduced | ES1 (1997) | ES6 (2015) | ES6 (2015) |
Scope | Function-scoped | Block-scoped | Block-scoped |
Hoisting | Hoisted with undefined (can be accessed before declaration) |
Hoisted but not initialized (ReferenceError if accessed before declaration) | Hoisted but not initialized (ReferenceError if accessed before declaration) |
Reassignment | ✅ Allowed | ✅ Allowed | ❌ Not allowed (must be assigned at declaration) |
Redeclaration | ✅ Allowed (even in the same scope) | ❌ Not allowed in the same scope | ❌ Not allowed in the same scope |
Mutability | ✅ Mutable | ✅ Mutable | ❌ Immutable (value cannot be reassigned) |
Global scope | ✅ Becomes a property of window object (window.varName )
|
❌ Does not become a property of window |
❌ Does not become a property of window |
Use case | Avoid using var due to scope issues |
Use when value needs to change | Use for FP style and constants (recommended!) |
var
var
let
or const
rather than var
let
, const
function getValue(condition){
// color hoisted here as undefined
if(condition){
var color = "blue";
return color;
}
else{
// color exists here as undefined
}
}
function getValue(condition){
// color does not exist here
if(condition){
let color = "blue";
return color;
}
else{
// color does not exist here
}
// color does not exist here
}
const
const MAX_USERS = 100;
const PI = 3.141592653589793;
PI = 3.14; // ❌ Error: Assignment to constant variable
PI = PI + 10; // ❌ Error: Assignment to constant variable
const
prevents reassignment of an object but
does not make the object itself immutable.
const user = { name: "Alice", age: 25 };
// ✅ Allowed: Modifying properties of an object
user.age = 30;
console.log(user.age); // 30
// ❌ Error: Reassigning the object itself
user = { name: "Bob", age: 40 };
// TypeError: Assignment to constant variable
let count, name; // variable does not have data type yet
count = 0; // number variable
name = "Charles Dickens"; // string variable
let number2 = 12; // new number variable
name = 123; // changed into an integer variable (!)
name = "New name"; // changed back to string, not allowed by const
let a = 5; // global variable
let sum = 0; // global variable
function doSomething() {
let b = 12; // local variable
c = 10; // global (!)
}
/* here b does not exist,
but c does */
window
object?
window
window
and document
window.document
refers to the DOM (Document Object Model).document
object lets JavaScript modify HTML and CSS dynamically.
console.log(window.document); // Outputs the full DOM tree
console.log(document === window.document); // true
window
window
: Using
globalThis
window
) and Node.js (global
)
environments.console.log(globalThis === window); // true in browsers
number
, string
, boolean
,
undefined
bigint
, symbol
null
(a special type representing "no value")Number
, String
, Boolean
,
Date
, Math
, RegExp
Array
and Function
are also objectslet seed = Math.random(); // random number between 0 and 1 [0,1)
let lottoNr = Math.floor(1 + 40*seed);
const start_date = new Date(2019,4,4,14,15);//year, month, day, hour, and minute
const month = start_date.getMonth(); // month = 4
let today = new Date();
const pattern = /[0-9]/;
const str = new String(today);
let found = str.match(pattern); // returns the first match
const str1 = 'This is a string';
const str2 = "So is this one";
const str3 = 'Here is "a quote", that is why both are used';
const str4 = "Here is \"a quote\", it can be done like this, as well";
const str5 = "123"; // this is a string, not a number
const str6 = "first row\nsecond row"; // would print on two rows
const start = "This is the start";
const end = "and this the end";
const mjono = start + ", " + end + "."; // "This is the start, and this the end."
const sosSecNr = "120289-123C";
const year = sosSecNr.substr(4, 2); // year on "89"
const bYear = "19" + year; // string "1989"
const year2 = year + 1; // string "891"
const year3 = parseInt(year) + 1; // number 90, parseInt() global function
const year4 = Number(year)+1; // number 90, Number() global function
let count = 12; // number 12
count = 12 + ""; // string "12"
const Dude = "Zelensky❤";
const str7 = `Hi ${Dude}, literals are strong weapons!`
// renders Dude's value to a string
true
and false
const married = true;
if (married) {
console.log("Let us be very married");
}
const b = (nr == 1000);
const notBoolean = "false"; // a string variable
true
and
false
in Boolean
context
undefined
null
null
in turn can be auto-casted into an empty
string,
null
or false
(depends on the receiving variable)
let n = 6, name = "TAU", arrOfSomething=[];
typeof(n) //returns 'number' (as a string)
typeof(name) //returns 'string' (as a string)
typeof(6 > 5) //returns 'boolean' (as a string)
let title;
typeof(title) //returns 'undefined' (as a string)
typeof(arrOfSomething) //returns object (not an array)
Array
object. To create
an
array of N
elements, you can writelet myArray = new Array(N);
length
tells the number of elements in the
array.
reverse()
, push()
, concat()
, flat()
etc.
// An array of 3 elements, each element is undefined
let Car = new Array(3);
// assign values to the elements
Car[0] = "Ford";
Car[1] = "Toyota";
Car[2] = "Honda";
// Create an array of three elements with initial values
let Car2 = new Array("Ford", "Toyota", "Honda");
// Create an array of three elements with initial values
let Car3 = ["Ford", "Toyota", "Honda"];
// An array of 3 elements with initial values of different types
let tmp3 = new Array(1, "a", true);
// Makes tmp3 an array of 10 elements
tmp3.length = 10; // from tmp[3] to tmp[9] undefined.
// Makes tmp3 an array of 100 elements
tmp3[99] = "Something";
// tmp[3] to tmp[98] are undefined. The array is sparse
Arrays can have items that are also arrays:
// Example: matrix
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// accessing items
let middle = matrix[1][1]; // 5
let firstInnerArray = matrix[0]; // [1, 2, 3]
let lastInnerArray = matrix.at(-1); // [7, 8, 9]
function addArrayItems(arrOfSomething){
if(Array.isArray(arrOfSomething)){
// all good, it's an array
}
}
typeof(arrOfSomething) //returns object (not an array)
arr.shift()
and
arr.unshift()
change the indices of the items
too
...
Spread syntax...
) syntax:
String
, Array
,
TypedArray
, Map
,
Set
...
Spread arrays// Copying array
const arr = [1, 2, 3];
const arr2 = [...arr]; // arr.slice()
arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected
// An alternative to concatenate arrays
const evens = [2, 4, 6, 8, 10];
const odds = [1, 3, 5, 7, 9];
const all = [...evens, ...odds]; // evens.concat(odds)
The method arr.concat() creates a new array that includes values from other arrays.
The arr.concat() method does not alter any of the arrays provided as arguments but instead returns a shallow copy that contains the same elements as the ones from the original arrays.
const letters = ['a', 'b', 'c'];
const numbers = [1, 2, 3];
const alphaNumeric = letters.concat(numbers);
// alphaNumeric: ["a", "b", "c", 1, 2, 3]
// "letters" and "numbers" arrays remain unaffected
for..of
Looping through arrays and other iterables
for...of
statement executes a loop that
operates on a sequence of values sourced from an iterable
object.
for..of
doesn't give access to the number of
the current element, just its value
Array
,
String
, Map
, Set
,
NodeList
(and other DOM collections)
break
and continue
work just like
inside any other loop
for..of
(continued)// Syntax
for (let value of iterable) {
// executes the body for each value of the iterable object
}
// Example
const fruits = ['Apple', 'Orange', 'Lemon'];
// iterates over array elements
for (let fruit of fruits) {
console.log(fruit); // "Apple", "Orange", "Lemon"
// NOTE: No access to the index/number of the element
// if that is needed, use regular for loop or
// use a separate variable to keep track of the index
}
for..of
Examplesconst obj = { a: 1, b: 2, c: 3 };
// Object.keys()
for (let key of Object.keys(obj)) {
console.log(key, obj[key]);
}
// Object.values()
for (let value of Object.values(obj)) {
console.log(value);
}
// Object.entries()
for (let [key, value] of Object.entries(obj)) {
console.log(key, value);
}
let variable = 5 + 6.0;
where | |
---|---|
5 + 6.0 | is expression |
5 and 6.0 | are operands |
+ | is operator |
// variables
// a and b are defined:
let a = 5;
let b = 10;
// let's assume the
// definitions:
let a = 5;
let b = 10;
let c = '10';
a + b // value is 15
a - b // value is -5
a * b // value is 50
a / b // value is 0.5
a % b // value is 5
a++ // value is 5
a-- // value is 5
(a == b) // value is false
(b == c) // value is true
(b === c) // value is false
(b != c) // value is false
(b !== c) // value is true
(a > b) // value is false
(a < c) // value is true
(b > c) // value is false
(b < c) // value is false
// let's assume the definitions:
let a = true;
let b = false;
(a && b) // value is false
(a || b) // value is true
!(a && b) // value is true
function isEven(n) {
return (n%2 == 0);
}
let val1 = 5;
let val2 = 4;
//conditional ternary operator
console.log(isEven(val1)?"is even":"is odd"); // is odd
console.log(isEven(val2)?"is even":"is odd"); // is even
// let's assume the definitions:
let a = 5;
let b = 10;
c = a + b; // c is 15
b += a; // b is 15
b -= a; // b is 5
b *= a; // b is 50
b /= a; // b is 2
b %= a; // b's value is 0
if(){..}
if (condition) {
statement;
}
[else {
statement;
}]
let age;
...
if (!age) {
ageGroup = "infant";
// ...
}
else if (age < 30) {
ageGroup = "teen";
// ...
}
else if (age < 65) {
ageGroup = "adult";
// ...
}
else ageGroup = "senior";
switch(){ … }
break
-statement makes the control leave the structureswitch (expression) {
case val1: statement;
[statement;]*
break;
case val2: statement;
[statement;]*
break;
...
case valN: statement;
[statement;]*
break;
default: statement(s);
}
switch (nr) {
case 10: alert("Number is 10");
break;
case 20: alert("Number is 20");
break;
default: alert("Nope, neither 10 nor 20");
}
for( ){ .. }
for (startStatement; loopCondition; change in the loop variable){
statement;
[statement;]*
}
for (let i=0; i<10; i++) {
sum=sum + table[i,j];
}
while(){ … }
while (condition) {
statement;
[statement;]*
}
break
continue
let i=10;
while (i>0) {
console.log(i+" ");
i--;
}
let i=10;
while (i>0) {
if (n===0) {
break;
}
console.log(i+i/n);
i--;
}
do { … } while( );
let count = 0;
console.log("Starting Loop");
do
{
document.write("Current Count : " + count");
count++;
} while (count < 5);
console.log("Loop stopped!");
function square(value) {
return value * value;
}
const radius = 6;
const area1 = 3.1459 * square(radius);
const someNumber = 3 + square(6 * radius);
function square(value) {return value * value;}
let square = function(value) {
return value * value;
}; // Note the semicolon!
const square = (value) => value * value;
const z = function(value){
return value * value;
} /* function expression */
const side1 = 3;
const newArea = z(side1);
const x = z;
const myArea = x(side1 + 6);
z
to a new variable x
x
now contains a callable function
console.group("Hoisting");
hoisted(); // ✅ Works (hoisted)
hoistedExp(); // ❌ TypeError: hoistedExp is not a function
hoistedExp2(); // ❌ ReferenceError: 'hoistedExp2' is not defined
console.groupEnd();
function hoisted() {
console.log("%cDeclaration is being hoisted", "color: green; font-weight: bold;");
}
var hoistedExp = function() {
console.log("%cExpression is not hoisted", "color: red; font-weight: bold;");
};
let hoistedExp2 = function() {
console.log("%cExpression is not hoisted", "color: red; font-weight: bold;");
};
function product(val1, val2) {
return val1 * val2;
} // 2 formal parameters
let width = 5, height= 6;
let area = product(width, height); // 2 actual parameters
let bigArea = product(10*width, 10*height); // 2 actual parameters
function product(val1, val2) {
return val1 * val2;
}
const x = product(1);
const y = product(3,4,5,6);
undefined
function add (){
let s = 0;
for (let i = 0; i < arguments.length; i++) {
s += arguments[i];
}
return s;
}
add(1, 2, 3); // returns 6
add(1, 2, 3, 4, 5); // returns 15
add(1, 2, "3", 4, 5); // what does this return?
function product(val1 = 10, val2 = 5) {
return val1 * val2;
}
let x = product(3,4);
let y = product(3);
let z = product(undefined, 6);
undefined
is returnedfunction isEven(n){
//function returns value of boolean expr.
return (n%2 ==0);
}
let val = 6;
if(isEven(val)){
//do something
}
function isEven(n) {
if((typeof(n)=="number")&&(!isNaN(n))){
return (n%2 ==0);
}
//else return value is undefined
}
let val = 5;
console.log(isEven(val)?"is even":"is odd");
//conditional ternary operator
function doSomething (p1){
if (typeof(p1) == "number")
return 0; // return a number
else
if (typeof(p1) == "string")
return "zero"; // return a string
}
doSomething(1); // returns 0
doSomething("abc"); // returns "zero"
doSomething(); // returns undefined
function invokeAdd(a,b){
return a() + b();
}
function one(){ return 1;}
function two(){ return 2;}
answer = invokeAdd(one, two);
function addArrayItems(arrOfSomething){
let sumOfItems = 0;
for (let i =0; i< arrOfSomething.length; i++){
sumOfItems += arrOfSomething[i];
}
return sumOfItems;
}
length
property to access the individual data items
function modArrayItems(arrOfSomething){
if(arrOfSomething.length > 0){
arrOfSomething[0] = 66;
}
return;
}
function modArrayItems(arrOfSomething){
if(arrOfSomething.length > 0){
arrOfSomething[0] = 66;
}
return;
}
let numbers = [3,4,4,5,6,7,9];
let names = ["pasi","leena","tuomo","kari","tiia"];
modArrayItems(numbers); //numbers Array [ 66, 4, 4, 5, 6, 7, 9 ]
modArrayItems(names); //names Array [ 66, "leena", "tuomo", "kari", "tiia" ]
// this is a comment
/* this is a multi-line
comment */
/**
* @param {string} student
* @returns {string} greeting for a student
* @description Return a greeting as a
template string. For demo purposes only.
*/
function demoJSDocs (student){
return `Hello ${student}, you WebDev
wanna-be`;
}