Intro to JS

Course on Scrimba.

Some prior programming experience is needed when reading these notes to understand things like variables, data types, and some data structures like arrays and objects.

Numbers

Strings

Boolean

Arrays

  let example1 = [5, 7, 6];
  
  example1.push(8, 9, 10); 	// adds all at end
  example1.pop(); 			// removes 10
  
  example1[0] = 1; 			// changes 5 to 1
  
  // used for iterating over each element
  example1.forEach((element) => {
      console.log(element);
  });
  
  console.log(example1)
  
  // Final output looks like this:
  // 1
  // 7
  // 6
  // 8
  // 9
  // [1, 7, 6, 8, 9]

Objects

Operators

Control Flow

Control flow is much like in C-like languages, so not much content is included here.

Conditionals

Iteration

Functions


Intro to ES6+

Course on Scrimba.

Some prior programming experience is needed when reading these notes to understand things like variables, data types, and some data structures like arrays and objects.

This course includes newly introduced features in ES6, ES7 and ES8. Some additions make JS a lot easier to use.

Template Strings

Destructuring

Essentially means that it gives shorthand codes to access and reassign values.

Destructuring Objects

Properties of objects can be accessed (and reassigned) in this shorthand as illustrated below:

const personalInformation = {
    firstName: 'John',
    lastName: 'Smith',
    city: 'Austin',
    state: 'Texas',
    zipCode: 73301
};

// direct access to props
const {firstName, lastName} = personalInformation;
// or, we can even reassign prop names
const {firstName: fn, lastName: ln} = personalInformation;

console.log(`${fn} ${ln}`); // returns "John Smith"

Destructuring Arrays

Like Objects above, destructuring can be done for Arrays as well, as shown:

let [firstName, middleName, lastName] = ['Neo', 'The', 'One'];

console.log(firstName + lastName); // NeoOne

Object Literals

Emphasizes writing less code.

If object literals are same as function arguments, we do not need to explicitly assign them as values.

function addressMaker(city, state) {
    // instead of:
    // const newAdress = {city: city, state: state};
    // write:
    const newAdress = {city, state};
    
    console.log(newAdress);
}

addressMaker('Austin', 'Texas'); // {city: 'Austin', state: 'Texas'}

For of Loop

In JavaScript, there is a for loop that iterates over an iterable data structure (like the for loop of Python), using which we can directly access the iterable’s elements.

let incomes = [62000, 67000, 75000];
let total = 0;

for (const income of incomes) {
    console.log(income);
    total += income;
}

console.log(total); // 204000

It is possible for strings also.

let fullName = "Neo The One";

// prints each character of fullName on a new line 
for (const char of fullName) {
    console.log(char);
}

Note: You cannot change the values of the element it is iterating over. It is not designed to do that.

Spread Operator

This operator, denoted as three dots - ... - is used to expand (or ‘spread’) an Array so that it can be copied to another (instead of referencing it).

let example1 = [1,2,3,4,5,6];
let example2 = [...example1];
example2.push(true);

console.log(example1);    // [1, 2, 3, 4, 5, 6]
console.log(example2);    // [1, 2, 3, 4, 5, 6, true]

It can be used with Objects as well.

Rest Operator

// without rest operator
function add(nums) {
console.log(nums);
}
add(4, 5, 7, 8, 12) // returns 4

// with rest operator
function add(...nums) {
console.log(nums);
}
add(4, 5, 7, 8, 12) // returns [4, 5, 7, 8, 12]

Arrow Functions

Extremely useful

function add(...nums) {
// here .reduce() applies the callback function
// to every element of the called Array.
let total = nums.reduce((x, y) => x + y);

console.log(total);
}

add(4, 5, 7, 8, 12) // returns 36

Default Params

function add(numArray = []) { // empty array by default
    let total = 0;
    numArray.forEach((element) => {
        total += element;
    });
    
    console.log(total);
}

add(); // notice we don't send in an arg, but it still returns 0

includes()

let and const

Import & Export

Allow us to follow the SOLID principles, do dependency injection, and object oriented programming, essentially helping us make our code more modular.

// example.js
export const data = [1,2,3];

// index.js
import { data } from './example.js';

console.log(data);    // returns [1, 2, 3]

Classes

// animal.js
export class Animal {
    constructor(type, legs) {
        this.type = type;
        this.legs = legs;
    }
    
    // we can define getters for our class
    get metaData() {
        return `Type: ${this.type}, Legs: ${this.legs}`;
    }
    
    makeNoise(sound = 'Loud Noise') {
        console.log(sound);
    }
}

// index.js
import { Animal } from './animal.js';

let cat = new Animal('Cat', 4);

cat.legs = 3;
cat.makeNoise();      // Loud Noise
cat.makeNoise('Meow');    // Meow
console.log(cat.legs)   // 3

// using getter of class
console.log(cat.metaData) // Type: Cat, Legs: 4
// animal.js
export class Cat extends Animal {
    constructor(type, legs, tail) {
        super(type, legs);
        this.tail = tail;
    }
    
    // this method overrides the parent class method
    makeNoise(sound = "meow") {
        console.log(sound);
    }
}

// index.js
import { Animal, Cat } from './animal.js'; // don't forget the Cat class too!

let cat = new Cat('Cat', 4);

cat.makeNoise();      // meow

// the following still works as properties are inherited from parent
console.log(cat.metaData);  // Type: Cat, Legs: 4

Promises, Async, and Await

const apiUrl = 'https://fcctop100.herokuapp.com/api/fccusers/top/alltime';

function getTop100Campers() {
    fetch(apiUrl)
    .then((r) => r.json())
    .then((json) => {
        console.log(json[0])
    }).catch((error) =>{
        console.log('failed');
    });
}

getTop100Campers();
// returns:
// {
//  username: "sjames1958gm",
//  img: "https://avatars1.githubusercontent.com/u/4639625?v=4",
//  alltime: 8826,
//  recent: 104,
//  lastUpdate: "2018-04-04T09:10:12.456Z"
// }
const apiUrl = 'https://fcctop100.herokuapp.com/api/fccusers/top/alltime';

async function getTop100Campers() {
    const response = await fetch(apiUrl);
    const json = await response.json();
    
    console.log(json[0]);
}

getTop100Campers();     // returns the same JSON as above
function resolveAfter3Seconds() {
  // here, we are creating a Promise object which is returned
  // once the inner function executes
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 3000);
  });
}

// this is the normal way, without async/await
// resolveAfter3Seconds().then((data) => {
//     console.log(data);
// });

async function getAsyncData() {
    const result = await resolveAfter3Seconds();
    console.log(result);
}

getAsyncData();     // returns "resolved" after 3s

Sets

Sets are unique lists of values and, much like the sets in Python and Java, these sets do not contain any duplicate values, even if initial assignment is made using duplicates.

const exampleSet = new Set([1,1,1,1,2,2,2,2]);
console.log(exampleSet);      // Set [ 1, 2 ]
console.log(exampleSet.size);   // 2

Sets have more functions such as .add(), .delete(), .has(), and .clear().