Monday ——————————–

Notes

Terminal Basics

The terminal is a text based system that allows you, as a user, to control your computer and do everything from creating new files and folders to starting up entire applications.

Descriptions of Programs we Installed


File Tree


Basic Terminal Navigation

Unix refers to the parent operating system upon which Mac is built on and Linux is inspired by.

Navigation Commands

Directory Shortcuts


Using Node JS

Javascript is the language of the internet!

Node REPL vs. Javascript File

Using the Node REPL

To enter the Node REPL simply type node into your terminal, you will be greeted with a > character - here you can type any JS code, and even define functions! (Just keep in mind these will not be saved)

Using Javascript Files


VCSode is an IDE (Interactive Developer Environment).

Please keep in mind that keeping an organized file system will save you a lot of trouble in the future!

VSCode Shortcuts


Tuesday———————————————————

Notes

The Object Type

The object is a data structure that stores other data, similar to how an array stores elements.

The Object of My Affections

In other programming languages, objects are referred to as, “dictionaries”, “maps”, or “associative arrays”.

Fun Fact: Objects are affectionately known as POJO’s (Plain Old Javascript Objects)

Setting Keys and Values

// here "color" is the key!
> car["color"] = "Blue";
"Blue"

> car["seats"] = 2;
2

// accessing our object at the key of color
> car["color"]
"Blue"

> car["seats"]
2

> car
{color: "Blue", seats: 2}
> car
{color: "Blue", seats: 2}

> "color" in car;
true

> "model" in car;
false

Using Variables as Keys

> car
{color: "Blue", seats: 2}

> let newVariable = "color";
undefined

> newVariable
"color"

> car[newVariable]
"Blue"

---

> car
{color: "Blue", seats: 2}

> newVariable
"weight"

// assigning a key value pair using a variable!
> car[newVariable] = 1000;
1000

> car
{color: "Blue", seats: 2, weight: 1000}

Using Different Notations

> let dog = {};
undefined

> dog.bark = "Bowowowo";
"Bowowowowo"

> dog.bark
"Bowowowo"

> dog
{ bark: "Bowowowowo" }

Bracket Notation vs Dot Notation

Dot Bracket
Easier To Read You can use variables as keys!
Easier To Write b/c do not need Quotations. Okay to use variables and Strings that start with numbers.
Cannot access with Variables
Keys cannot contain numbers as their first character
let myDog = {};
myDog.name = "Fido";

let myKey = "name";
console.log(myDog); // prints `{name: "Fido"}`
console.log(myDog[myKey]); // prints `Fido`

console.log(myDog.myKey); // prints: undefined

Putting it All Together

You can put an object together in a single statement.

let myDog = {
    name: "Fido",
    type: "Doge",
    age: 2,
    favoriteToys: ["bone", "ball"],
};

Operator Precedence Revisited


Iterating Through Objects

Because objects store unordered key-value pairs, we do not rely on indices to access values; instead we rely on our keys.

A New Kind of For Loop

for (let variable in object) {
    statement;

    let obj = { name: "Rose", cats: 2 };
    for (let currentKey in obj) {
        console.log(currentKey);
        console.log(obj[currentKey]);
    }

    // prints out:
    // name
    // cats
    // Rose
    // 2
}

Methods vs Functions

A Method is a function that belongs to an object. Every method is a function, but not every function is a method.

myFunc is a function
myObject.myFunc is a method of the object myObject
myObject["myFunc"] is a method of the object myObject
let dog = {
    name: "Fido",
};

dog.bark = function () {
    console.log("bark bark!");
};

// this is the same thing as above just using Bracket Notation
dog["speak"] = function (string) {
    console.log("WOOF " + string + " WOOF!!!");
};

dog.bark(); // prints `bark bark!`
dog.speak("pizza"); // prints `WOOF pizza WOOF!!!`

let dog2 = {
    name: "Rover",

    bark: function () {
        console.log("bork bork!");
    },

    speak: function (string) {
        console.log("BORK " + string + " BORK!!!");
    },
};
// Notice that in the object above, we still separate the key-value pairs with commas.
// `bark` and `speak` are just keys with functions as values.

dog2.bark(); // prints `bork bork!`
dog2.speak("burrito"); // prints `BORK burrito BORK!!!`
myObject.methodName();

Useful Object Methods

Iterating through an Object’s keys & values

> Object.entries(cat)
[ [ 'name', 'Freyja' ], [ 'color', 'orange' ] ]

References vs Primitives

Primitives vs Objects

So far we have learned about 6 different data types:

Immutabiity

pic of nums
pic of nums

Mutabulity

img of mut
img of mut

Rest and Spread

Using the Spread Operator and Rest Parameter Syntax Accepting Arguments

Utilizing Rest Parameters

Utilizing Spread Syntax

let numArray = [1, 2, 3];

// here we are taking `numArray` and *spreading* it into a new array where
// comma separated elements are expected to be
let moreNums = [...numArray, 4, 5, 6];

> moreNums
// => [1, 2, 3, 4, 5, 6]

With Objects

let colors = { red: "scarlet", blue: "aquamarine" };
let newColors = { ...colors };

> newColors
// { red: "scarlet", blue: "aquamarine" };
let colors = { red: "scarlet", blue: "aquamarine" };
let colors2 = { green: "forest", yellow: "sunflower" };

let moreColors = { ...colors, ...colors2 };

> moreColors
// {red: "scarlet", blue: "aquamarine", green: "forest", yellow: "sunflo

Spreading Arguments

function speak(verb, noun) {
    return "I like to go " + verb + " with " + noun + ".";
}

const words = ["running", "Jet"];

console.log(speak("running", "Jet")); // => I like to go running with Jet.
console.log(speak(...words)); // => I like to go running with Jet.

Destructuring

let numArray = [10, 20];

// here we are "unpacking" the array values into two separate variables
let [firstEl, secondEl] = numArray;

console.log(firstEl); //=> 10
console.log(secondEl); //=> 20

Swapping Variables using destructuring

let num1 = 17;
let num2 = 3;

// this syntax will swap the values of the two variables
[num1, num2] = [num2, num1];

console.log(num1); // 3
console.log(num2); // 17

Destructuring objects into variables

let obj = { name: "Apples", breed: ["tabby", "short hair"] };
let { name, breed } = obj;

console.log(name); // "Apples"
console.log(breed); // ["tabby", "short hair"]
let obj = { apple: "red", banana: "yellow" };
let { apple: newApple, banana: newBanana } = obj;

console.log(newApple); // "red"
console.log(newBanana); // "yellow"
// the fname key is nested more than two levels deep
// (within bootcamp.instructor.fullName)
let bootcamp = {
    name: "App Academy",
    color: "red",
    instructor: {
        fullName: {
            fname: "Rose",
            lname: "K",
        },
    },
};

// this is hard to follow:
let {
    instructor: {
        fullName: { fname, lname },
    },
} = bootcamp;
console.log(fname, lname);

// this is much easier to read:
let { fname, lname } = bootcamp.instructor.fullName;
console.log(fname, lname);

Destructuring and the Rest Pattern

let foods = ["pizza", "ramen", "sushi", "kale", "tacos"];

let [firstFood, secondFood, ...otherFoods] = foods;
console.log(firstFood); // => "pizza"
console.log(secondFood); // => "ramen"
console.log(otherFoods); // => ["sushi", "kale", "tacos"]
let { a, c, ...obj } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a); // => 1
console.log(c); // => 3
console.log(obj); // => { b: 2, d: 4 }

Destructuring Parameters

We can also destructure incoming parameters of a function. This is very useful when we’re passing objects around to different functions.

let cat = { name: "Rupert", owner: "Curtis", weight: 10 };

// This unpacks the *owner* key out of any incoming object argument and
// assigns it to a owner parameter(variable)
function ownerName({ owner }) {
    console.log("This cat is owned by " + owner);
}

ownerName(cat);
let bigCat = {
    name: "Jet",
    owner: { name: "Rose" },
    toys: ["ribbon"],
    siblings: { name: "Freyja", color: "orange", toys: ["mouse", "string"] },
};

// here we use *aliased* object destructuring to create a siblingToys variable
function toyFinder({ toys, siblings: { toys: siblingToys } }) {
    let allToys = toys.concat(siblingToys);
    return allToys;
}

console.log(toyFinder(bigCat)); // => ["ribbon", "mouse", "string"]

Plain Old JS Object Lesson Learning Objectives (W2D2) - Learning Objectives

  1. Label variables as either Primitive vs. Reference There are 5 primitive data types: Boolean, Null, Undefined, Number, String 1 Reference Type: Object (arrays are a kind of object)
  2. Identify when to use . vs [] when accessing values of an object:
//Using [](bracket) notation

let person = {};

person["firstName"] = "Jesse";
console.log(person);
person["firstName"] = "Steven";

console.log(person);

//Using . (dot) notation

let person = {};

person.name = "Brian";
console.log(person);
person.name = "Steven";
console.log(person);
  1. Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object

Checking for Undefinied with bracket notation

let person = {};
person.name = "Paul";
person.age = 25;
console.log(person);
console.log(person["name"] === "Paul");
console.log(person["age"] === 25);
console.log(person["occupation"] === undefined);
console.log(person["occupation"] !== undefined);
  1. Utilize Object.keys and Object.values in a function
//Object.keys

let cars = { make: "honda", model: "civic" };
console.log(Object.keys(cars));

//Object.values

let cars = { make: "honda", model: "civic" };
console.log(Object.values(cars));
  1. Iterate through an object using a for in loop
let obj = { game: "call of duty", console: "PC duh?" };

for (let keys in obj) {
    let values = obj[keys];
    console.log("Here are the key value pairs!", keys, "-", values);
}
  1. Define a function that utilizes …rest syntax to accept an arbitrary number of arguments
let acceptEverything = function (...everything) {
    console.log(everything);
};

acceptEverything("thing1", "thing2", "thing3");
  1. Use …spread syntax for Object literals and Array literals
let arrayOfNums = [0, 1, 2, 3, 4];

let moreNums = [...arrayOfNums, 5, 6, 7, 8, 9];

console.log(moreNums);

let hubby = { firstName: "John", lastName: "Doe" };
let wifey = { firsName: "Jane", lastName: "Doe" };

let couple = { ...hubby, ...wifey };
//Something interesting happens here
console.log(couple);

let person1 = { name: "Jack", faveColor: "red" };
let person2 = { name: "Paul", faveColor: "blue" };
let people = { ...person1, ...person2 };
console.log(people);
  1. Destructure an array to reference specific elements
let nums = [1, 2];

let [num1, num2] = nums;

console.log("num1 variable", num1, " num2 variable", num2);
  1. Destructure an object to reference specific values
let person = {
    name: "Kelly",
    getFaveColor: function () {
        return "blue";
    },
    friends: {
        name: "Ryan",
    },
};

let {
    friends: { name },
} = person;

console.log("name", person.name);
console.log("favorite color", person.getFaveColor());
console.log(name);
  1. Write a function that accepts a array as an argument and returns an object representing the count of each character in the array
let myCounter = function (array) {
    let myObj = {};
    let count = 1;
    array.forEach(function (char) {
        if (myObj[char] === undefined) {
            myObj[char] = count;
        } else {
            myObj[char]++;
        }
    });
    return myObj;
};

console.log(myCounter(["a", "a", "n", "c"]));

Wednesday —————————————————————————————————————————–

Notes

Callbacks: Using a Function as an Argument

What is a callback?

let foobar = function (callback) {
    console.log("foo");
    callback();
    console.log("bar");
};

let sayHello = function () {
    console.log("hello");
};

foobar(sayHello); // prints
// foo
// hello
// bar
let foobar = function (callback) {
    console.log("foo");
    callback();
    console.log("bar");
};

foobar(function () {
    console.log("hello");
}); // prints
// foo
// hello
// bar

A More Interesting Example

let add = function (num1, num2, cb) {
    let sum = num1 + num2;
    let result = cb(sum);
    return result;
};

let double = function (num) {
    return num * 2;
};

console.log(add(2, 3, double)); // 10
let add = function (num1, num2, cb) {
    let sum = num1 + num2;
    let result = cb(sum);
    return result;
};

console.log(add(60, 4, Math.sqrt)); // 8

Refactoring for an Optional Callback

let add = function (num1, num2, cb) {
    if (cb === undefined) {
        return num1 + num2;
    } else {
        return cb(num1 + num2);
    }
};

console.log(add(9, 40)); // 49
console.log(add(9, 40, Math.sqrt)); // 7

Callback Functions as First Class Objects


Callback Functions Demo

Interesting Interaction.

let foo = function () {
    let bar = function () {
        console.log("interesting");
    };
    return bar;
};

console.log(foo()); // [function: bar]

let res = foo();
console.log(rest); // interesting.

Thursday ——————————————————————————–

Notes

All About Scope in Javscript

The scope of a program in JS is the set of variables that are available for use within the program.

Advantages of utilizing scope

Different Kinds of Scope

Scope Chaining: Variables and Scope

let name = "Fiona";

// we aren't passing in or defining and variables
function hungryHippo() {
    console.log(name + " is hungry!");
}

hungryHippo(); // => "Fiona is hungry"

Lexical Scope


Different Variables in Javascript

The different ways to declare variables

Hoisting and Scoping with Variables

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

Function-Scoped Variables

Hoisting with function-scoped variables

function test() {
    // var hoistedVar;
    console.log(hoistedVar); // =>  undefined
    var hoistedVar = 10;
}

Block-Scoped Variables

Things that create block-scopes:

Properties of Constants

Hoisting with block-scoped variables

Function Scope vs Block Scope

Global Variables


Closures

Calculating Closures

Closures and Scope Basic Closure Rules:

Applications of Closures


Context in Javascript

What about this ?

Issues with Scope and Context

When Methods have an Unexpected Context

let dog = {
    name: "Bowser",
    changeName: function () {
        this.name = "Layla";
    },
};

let change = dog.changeName;
console.log(change()); // undefined

console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] }

console.log(this); // Object [global] {etc, etc, etc,  name: 'Layla'}

Strictly Protecting the Global Object

We can run JS in strict mode by tagging use strict at the top of our program.

Changing Context using Bind

“The simplest use of bind() is to make a function that, no matter how it is called, is called with a particular this value”.

let cat = {
    purr: function () {
        console.log("meow");
    },
    purrMore: function () {
        this.purr();
    },
};

let sayMeow = cat.purrMore;
console.log(sayMeow()); // TypeError

let boundCat = sayMeow.bind(cat);

boundCat(); // prints "meow"

Binding with Arguments


Arrow Functions aka Fat Arrows

Arrow Functions Solving Problems

let average = function (num1, num2) {
    let avg = (num1 + num2) / 2;
    return avg;
};

let averageArrow = (num1, num2) => {
    let avg = (num1 + num2) / 2;
    return avg;
};

As you can see the arrow function is shorter and easier to read.

Anatomy of an Arrow Function

Single Expression Arrow Functions