| Work | Research and Development (R&D) | Engineering | Development | JavaScript Crash Course For Beginners
JavaScript Crash Course For Beginners

https://www.youtube.com/watch?v=hdI2bqOjy3c

What is Javascript?

Why learn Javascript?

What you will learn in this course

Further Learning

Script Tags

Script tags can be inline with HTML or referenced in a separate fie.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JS Crash Course</title>
</head>
<body>
  <header>
    <h1>JS Crash Course</h1>
  </header>
  <script src="main.js"></script>
</body>
</html>

main.js

alert('Hello World');

Console Output

To see a full list of methods available in the console see https://developer.mozilla.org/en-US/docs/Web/API/console

main.js

console.log('Hello World');
console.error('This is an error');
console.warn('This is a warning');

Variables

// var, let, const
// var is globally scoped which can cause conflicts
// let, const were added in ES6

// let allows you to reassign values
let age = 30;
age = 31;
console.log(age);

// const does not allow you to reassign values and will throw an error
// const age = 30;
// age = 31;
// console.log(age);

// general rule, always use const unless you know you're going to reassign a value

Data Types

// Primitive data types where data is directly assigned to memory.
// String, Numbers, Boolean, null, undefined, Symbol (added in ES6)

const name = 'John'; // String
const age = 30; // Number
const rating = 4.5; // Number
const isCool = true; // Boolean
const x = null; // null (incorrectly shows object)
const y = undefined; // undefined
let z; // undefined

console.log(typeof z);

Strings and String Methods

// Concatenation

const name = 'John'; // String
const age = 30; // Number
console.log('My name is ' + name + 'and I am ' + age);

// Template String 

const hello = `My name is ${name} and I am ${age}`;
console.log(hello);

// String Property and Methods

const s = 'Hello World!';
console.log(s.length);
console.log(s.toUpperCase());
console.log(s.toLowerCase());
console.log(s.substring(0, 5));
console.log(s.substring(0, 5).toUpperCase());
console.log(s.split(''));

const s = 'technology, computers, it, code'
console.log(s.split(', '));

Arrays

// Arrays - ariables that hold multiple values

// const numbers = new Array(1,2,3,4,5);
// console.log(numbers);

// const fruits = ['apples', 'oranges', 'pears'];
// console.log(fruits);

// In JavaScript, you can have multiple data types in an array. 

// const fruits = ['apples', 'oranges', 'pears', 10, true]
// console.log(fruits);
// console.log(fruits[1]);

// JavaScript is not statically typed. (Typescript, a superset of JavaScript is statically typed)
// Arrays are 0 based, so the first position is always 0.

const fruits = ['apples', 'oranges', 'pears']

// Inserting data to a specific location in an array
fruits[3] = 'grapes';
console.log(fruits);

// Inserting data to the end of an array
fruits.push('mangos');
console.log(fruits);

// Inserting data to the beginning of an array
fruits.unshift('strawberries');
console.log(fruits);

// Remove the last item in an array
fruits.pop();
console.log(fruits);

// Check to see if something is an array
console.log(Array.isArray(fruits));
console.log(Array.isArray('fruits'));

// Find the index of something in an array
console.log(fruits.indexOf('oranges'));

Object Literals

// Object literals are key value pairs

const person = {
    firstName: 'John',
    lastName: 'Doe',
    age: 30,
    hobbies: ['music', 'movies', 'sports'],
    address: {
        street: '50 main st',
        city: 'Boston',
        state: 'MA'
    }
}

console.log(person)

// If you want to access a single value, you should use the dot syntax
console.log(person.firstName);
console.log(person.firstName, person.lastName);
console.log(person.hobbies[1])
console.log(person.address.city)

// Destructuring - create variables by pulling these out of an object
const { firstName, lastName } = person;
console.log(firstName);

const { address: {city} } = person;
console.log(city);

const { street } = person.address;
console.log(street);

// To add properties
person.email = 'john@gmail.com';
console.log(person);

Arrays Of Objects & JSON

const todos = [
    {
        id: 1,
        text: 'Take out trash',
        isCompleted: true
    },
    {
        id: 2,
        text: 'Meeting with boss',
        isCompleted: true
    },
    {
        id: 3,
        text: 'Dentist appointment',
        isCompleted: false
    },
];

console.log(todos[1].text);

// JSON formatter adds ""

const todoJSON = JSON.stringify(todos);
console.log(todoJSON);

Loops

// For Loop

for(let i = 0; i <= 10; i++) {
    console.log(`For loop Number: ${i}`)
}

// For loops accept three parameters, the first is the iterator or variable, next is the condition, lastly is the increment.

// While Loop

// The difference between a For loop and a While loop is that we set the variable outside of the loop.

let i = 0;
while(i < 10) {
    console.log(`While loop Number: ${i}`);
    i++;
}

// While loop only accepts one parameter which is the conditional.

// How to loop through arrays

const todos = [
    {
        id: 1,
        text: 'Take out trash',
        isCompleted: true
    },
    {
        id: 2,
        text: 'Meeting with boss',
        isCompleted: true
    },
    {
        id: 3,
        text: 'Dentist appointment',
        isCompleted: false
    },
];

for(let i = 0; i < todos.length; i++) {
    console.log(todos[i].text);
}

// For of

for(let todo of todos) {
    console.log(todo.text)
}

High Order Array Methods

const todos = [
    {
        id: 1,
        text: 'Take out trash',
        isCompleted: true
    },
    {
        id: 2,
        text: 'Meeting with boss',
        isCompleted: true
    },
    {
        id: 3,
        text: 'Dentist appointment',
        isCompleted: false
    },
];

// forEach, map, filter

todos.forEach(function(todo) {
    console.log(todo.text)
});

// map returns an array

const todoText = todos.map(function(todo){
    return todo.text;
});

console.log(todoText);

// filter 

// const todoCompleted = todos.filter(function(todo){
//     return todo.isCompleted === true;
// });

// console.log(todoCompleted);

// you can also chain other array methods

const todoCompleted = todos.filter(function(todo){
    return todo.isCompleted === true;
}).map(function(todo){
    return todo.text;
})

console.log(todoCompleted);

Conditionals

const x = 11;

// using == does not match data types, only matches values

if(x == 10) {
    console.log('x is 10');
}

// using === does match data types. It's good practice to default to using ===

if(x === 10) {
    console.log('x is 10');
}

// example using else

if(x === 10) {
    console.log('x is 10');
} else {
    console.log('x is NOT 10')
}

// example using else if 

if(x === 10) {
    console.log('x is 10');
} else if(x > 10) {
    console.log('x is greater than 10')
} else {
    console.log('x is NOT 10')
}

// multiple conditions

const y = 10;

if(x > 5 || y > 10) {
    console.log('x is more than 5 OR y is more than 10')
}

if(x > 5 && y > 10) {
    console.log('x is more than 5 AND y is more than 10')
}

// ternary operator. If this statement is true ? value if true : value if false

const color = x > 10 ? 'red' : 'blue'
console.log(color);

// switches

switch(color) {
    case 'red':
        console.log('color is red');
        break;
    case 'blue':
        console.log('color is blue');
        break;
    default:
        console.log('color is not red or blue');
}

Functions

// Functions

// Call the function and add in parameters.

function addNums(num1, num2) {
    console.log(num1 + num2)
}

addNums(5,4);

// Set default values for your parameters

function addNums(num1 = 1, num2 = 1) {
    console.log(num1 + num2)
}

addNums(5,5);

// Functions typically return a value

function addNums(num1 = 1, num2 = 1) {
    return num1 + num2
}

console.log(addNums(5,5));

// arrow function introduced in ES6 (2015). Name as variable

const addNums = (num1 = 1, num2 = 1) => {
    return num1 + num2
}

console.log(addNums(5,5));

// since there's only one expression, you don't even need {}, you can do it in one line.

const addNums = (num1 = 1, num2 = 1) => console.log(num1 + num2)

console.log(addNums(6,7));

const addNums = (num1 = 1, num2 = 1) => num1 + num2

console.log(addNums(6,7));

// if you only have one parameter, you don't even need paranthesis

const addNums = num1 => num1 + 5

console.log(addNums(5));

// this can also be applied to loops like forEach 

todos.forEach((todo) => console.log(todo));

Constructor Functions and Prototypes

function Person(firstName, lastName, dob) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.dob = new Date(dob);
    // You can create methods and add it to the person object
    this.getBirthYear = function () {
        return this.dob.getFullYear();
    }
    this.getFullName = function() {
        return `${this.firstName} ${this.lastName}`;
    }
}

// Instantiate object
const person1 = new Person('John', 'Doe', '1980-4-2');
const person2 = new Person('Mary', 'Smith', '1970-6-3')

console.log(person2.dob)

// With date, there are bunch of available methods you can use
console.log(person2.dob.getFullYear());

// You can create methods and add it to the person object
console.log(person1.getBirthYear());

console.log(person1.getFullName());

// Prototypes are another object that we can attach methods and objects to. We can remove the functions from every object instance as we may not use it, we can instead move these into the prototype object instead.

Person.prototype.getBirthYear = function() {
    return this.dob.getFullYear();
}

Person.prototype.getFullName = function() {
    return `${this.firstName} ${this.lastName}`;
}

console.log(person1);

Classes

// ES6 added classes (ES6 = ES2015). With classes, it adds methods to prototype but with syntax sugar. You don't have to use classes, they're just cleaner / more organized to write.

class Person {
    constructor(firstName, lastName, dob) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.dob = new Date(dob);
    }

    // A method is a function inside of a class
    // Adding these methods to the class adds them to the prototype
    getBirthYear() {
        return this.dob.getFullYear();
    }

    getFullName() {
        return `${this.firstName} ${this.lastName}`;
    }
}

// Instantiate object
const person1 = new Person('John', 'Doe', '1980-4-2');
const person2 = new Person('Mary', 'Smith', '1970-6-3')

console.log(person2.getFullName());
console.log(person1);

DOM

// DOM

//// The DOM is the document object model. It is the tree structure of your whole document including your HTML tags. 
//// In the browser you have a window Object. The window object is the parent object of the browser. 

console.log(window);
window.alert(1);
alert(1);

// Single element selectors

//// If there is more than one element it will only select the first one.

//// The document is part of the window. Document is what makes up the DOM.
console.log(document.getElementById('my-form'));

const form = document.getElementById('my-form');
console.log(form);

//// querySelector works like JQuery for selecting classes

console.log(document.querySelector('.container'));
console.log(document.querySelector('h1'));

// Multiple element selectors

//// querySelectorAll is used for selecting multiple classes. It returns a NodeList which you can run array methods on. This is the recommended approach.

console.log(document.querySelectorAll('.item'));

//// getElementsByClassName and getElementsByTagName are available but are older and less used. They returnsa HTML collection which you can't use array methods on.
console.log(document.getElementsByClassName('item'));
console.log(document.getElementsByTagName('item'));

// Select and loop through 

const items = document.querySelectorAll('.item');

items.forEach((item) => console.log(item));

const ul = document.querySelector('.items');

// to delete the ul
// ul.remove();

// to delete the last ul
// ul.lastElementChild.remove();

// ul.firstElementChild.textContent = 'Hello';
// ul.children[1].innerText = 'Brad';
// ul.lastElementChild.innerHTML = '<h4>Hello</h4>'

const btn = document.querySelector('.btn');
// btn.style.background = 'red';

Events

// click
btn.addEventListener('click', (e) => {

    // this stops the default behavior from proceeding
    e.preventDefault();
    console.log('click');

    // inspect the event
    console.log(e);

    // inspect target element
    console.log(e.target);
    console.log(e.target.className);
    console.log(e.target.id);

    // changing background of form on button click
    document.querySelector('#my-form').style.background = '#ccc';

    document.querySelector('body').classList.add('bg-dark');

    document.querySelector('.items').lastElementChild.innerHTML = '<h1>Hello</h1>';
});

// mouseover
btn.addEventListener('mouseover', (e) => {
    console.log('mouseover'); 
});

// mouseout
btn.addEventListener('mouseout', (e) => {
    console.log('mouseover'); 
});

Form Script

// Form Script

const myForm = document.querySelector('#my-form');
const nameInput = document.querySelector('#name');
const emailInput = document.querySelector('#email');
const msg = document.querySelector('.msg');
const userList = document.querySelector('#users');

myForm.addEventListener('submit', onSubmit);

function onSubmit(e) {
    e.preventDefault();
    console.log(nameInput.value);

    if(nameInput.value === '' || emailInput.value === '') {
        msg.classList.add('error');
        msg.innerHTML = 'Please enter all fields';
        setTimeout(() => msg.remove(), 3000);
    } else {
        console.log('success');
        const li = document.createElement('li');
        li.appendChild(document.createTextNode(`${nameInput.value} : ${emailInput.value}`));
        userList.appendChild(li);

        // Clear fields
        nameInput.value = '';
        emailInput.value = '';
    }
}