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.
The Terminal
The Command Prompt
Descriptions of Programs we Installed
VSCODE
: a free source-code editor made by Microsoft for Windows, Linux and macOS.Node
: an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside a web browser.NPM
: a package manager for the JavaScript programming language.Mocha
: a JavaScript test framework for Node.js programs.Xcode Command Line Tools
: The Command Line Tool package gives Mac terminal users many commonly used tools, utilities, and compilersHomebrew
: a free and open-source software package management system that simplifies the installation of software.Python 3
: an interpreted, high-level, general-purpose programming language.Directory
: Same as a folder on your computer; a directory can contain many files or subdirectories (folders within themselves)Root
: The outermost main directory of our computer represented by /Path
: Location on your computer specified by directories. /Desktop/photos/cats.pdf
is an example of a path.CLI
: The Command Line Interface is the text-based user interface used to view and manage computer files.
GUI
: The Graphic User Interface is the visual alternative of the CLI, it is what we have been using to navigate our computers so far.Unix refers to the parent operating system upon which Mac is built on and Linux is inspired by.
~
(tilde) which denotes your home directory
.Navigation Commands
ls
: lists all files and subdirectories in the current directory.cd [path]
: changes the current directory to the directory specified by the path argument.pwd
: The present working directory command lists the path from your current location starting from root.clear
: Clears your terminal.Directory Shortcuts
cd ..
or cd
by itself to quickly naviagte to your previous directory.Javascript is the language of the internet!
Google Chrome
& Node
.Node
is a very powerful runtime environment built on Google Chrome’s Javascript V8 Engine.Runtime Environment
: A runtime system that is used to implement portions of an execution model.Node REPL vs. Javascript File
Node REPL
.js 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)
. exit
or ctrl + c.Using Javascript Files
mkdir <folder name>
.touch <file name.js>
.node <file name>
.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
The object
is a data structure that stores other data, similar to how an array stores elements.
value
stores in an obj is associated with a key
.The Object of My Affections
In other programming languages, objects are referred to as, “dictionaries”, “maps”, or “associative arrays”.
keys
instead of numbers.{}
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}
in
operator.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}
> 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.
Operator Precedence Revisited
Right Associativity
: When code is evaluted right to left.
Left Associativity
: When code is evaluated left to right.
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
}
for-in loop
.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!!!`
Useful Object Methods
Object.keys()
: A method that allows us to iterate through keys, it accepts an obj as the argument and returns an array of the keys.Object.values()
: Method that accepts an object as the argument and returns an array of the values.Iterating through an Object’s keys & values
Object.entries
: Method that accepts an object as the argument and returns an array of the [key,value] pairs within.Primitives vs Objects
So far we have learned about 6 different data types:
Immutabiity
Mutabulity
Using the Spread Operator and Rest Parameter Syntax Accepting Arguments
Utilizing Rest Parameters
Rest Parameter Syntax
: Allows us to capture all of a function’s incoming arguments into an array.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 Syntax
: Allows you to extract parts of an array or obj intro distinct variables.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 }
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"]
//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);
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);
//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));
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);
}
let acceptEverything = function (...everything) {
console.log(everything);
};
acceptEverything("thing1", "thing2", "thing3");
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);
let nums = [1, 2];
let [num1, num2] = nums;
console.log("num1 variable", num1, " num2 variable", num2);
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);
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"]));
What is a callback?
callback
is always a function that is being passed into another function.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
Anonymous Callback
: When we use a function expression directly.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
Math.sqrt
built in function being passed directly in as an argument.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
First-Class Object
: A type that supports the same basic operations as most other types. (i.e. Numbers, Strings & Booleans)First-Class Objects must be able to do three things:
They can be returned in functions.
Higher-Order Function
: A function that should either accept another function as an argument, or return a function as an output.Callback Functions are passed into Higher-Order Functions.
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.
The scope
of a program in JS is the set of variables that are available for use within the program.
Advantages of utilizing scope
Security
: Adds security by ensuring variables can only be access by pre-defined parts of our program.Reduced Variable Name Collisions
: Restricts re-using variable names; helps prevent overwriting variable names.Different Kinds of Scope
Global Scope
window
obj in the browser and the global
obj in Node.js.Local Scope
Block 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"
Scope Chaining
: When a variable is not found within the immediate scope, JS will keep searching outwards until it matches the one we are referencing.Lexical Scope
Lexing Time
: When you run a piece of JS code that is parsed before it is run.
JS language does not have dynamic scope.
The different ways to declare variables
let
: can be re-assigned; block-scoped.const
: no re-assignment; block scoped.var
: May or may not be re-assigned; scoped to a function.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
Temporal Dead Zone
: The time before a let or const variable is declared.Function Scope vs Block Scope
Global Variables
global scope
.Calculating Closures
Lexical Environment
: Consists of any variables available within the scope in which a closure was declared (local inner, outer, and global).Closures and Scope Basic Closure Rules:
Applications of Closures
Passing Arguments Implicitly
Scope
: Refers to the visibility and availability of variables.Context
: Refers to the value of the this
keyword when code is executed.What about this
?
This
: Keyword that exists in every function and evaluates to the object that is currently invoking that function.object.method(arg)
. (i.e. array.push, str.toUpperCase()Context
refers to the value of this within a function and this
refers to where a function is invoked.Issues with Scope and Context
this
is called using normal function style invocation, our output will be the contents of the global object.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'}
global.setTimeout()
: popular method of setting a function to run on a timer.
Accepts a callback and a number of milliseconds to wait before invoking the callback.
```js
let hello = function () {
console.log("hello!");
};
// global. is a method of the global object!
global.setTimeout(hello, 5000); // waits 5 seconds then prints "hello!"
```
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
We can also use bind() to bind arguments to a function.
=>
: A more concise way of declaring a function and also considers the behavior of this
and context.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
this
lexically.this
inside an arrow function is not dependent on how it is invoked.this
.