1 // Primitive Data Types 2 3 var myString = 'hello world!'; 4 var myInteger = 1; 5 var myBoolean = true; 6 var noValue = null; 7 var notDefined = undefined;
Primitive data types cannot be changed
(they're NOT mutable)
1 var myObject = { 2 key: "value" 3 }; 4 var myArray = [1, 2, 3]; 5 var myFunction = function() { 6 return "let's code!"; 7 };
Objects
(and arrays and functions since they're just special types of objects)
can be changed (they ARE mutable)
[]
var students = ["Julia", "Johnny", "Jose"];
Arrays are good for storing lists of values
They can store any type of JavaScript value,
both primative
var mixt = ["Hello, it's me", 2, true];
var mixt = ["Hello, it's me", 2, true];
var moreMixt = [ [0,1], {hello: "world"}, 5 ];
They can store any type of JavaScript value,
both primative and non-primative
var students = ['Julia', 'Johnny', 'Jose'];
0
2
1
Index:
Arrays store values at numeric indexes
We can access any value using this index and bracket notation
students[0]; // "Julia"
students[1]; // "Jonny"
students[2]; // "Jose"
students[3]; // undefined
You can also use bracket notation
to assign values at index positions
// ASSIGN NEW INDEX:
students[3] = 'Jo';
students // ['Julia', 'Johnny', 'Jose', 'Jo']
var students = ['Julia', 'Johnny', 'Jose'];
Index:
0
1
2
// OR OVERWRITE OLD INDEX:
students[1] = 'Jamil';
students // ['Julia', 'Jamil', 'Jose', 'Jo']
// ASSIGN NEW INDEX:
students[3] = 'Jo';
students // ???
// OR OVERWRITE OLD INDEX:
students[1] = 'Jamil';
students // ???
You can use dot notation to access
native methods that all arrays come pre-built with
students.length; // 3
var students = ['Julia', 'Johnny', 'Jose'];
Index:
0
1
2
students.length; // 3
students[3] = "Jo";
students; // ["Julia", "Johnny", "Jose", "Jo"]
students.length; // 4
1. LENGTH Property:
You can use dot notation to access
native methods that all arrays come pre-built with
students.length; // 3
students.push("Jin");
students; // ??
students.length; // ??
var students = ['Julia', 'Johnny', 'Jose'];
Index:
0
1
2
students.length; // 3
students.push("Jin");
students; // ["Julia", "Johnny", "Jose", "Jin"]
students.length; // 4
2. PUSH Method:
You can use dot notation to access
native methods that all arrays come pre-built with
students.length; // 3
students.pop();
students; // ??
students.length; // ??
var students = ['Julia', 'Johnny', 'Jose'];
Index:
0
1
2
students.length; // 3
students.pop();
students; // ["Julia", "Johnny"]
students.length; // 2
3. POP Method:
You can use dot notation to access
native methods that all arrays come pre-built with
students.sort();
students; // ??
var students = ['Julia', 'Johnny', 'Jose'];
Index:
0
1
2
students.sort();
students; // ["Johnny", "Jose", "Julia"]
3. SORT Method:
Because arrays have a set order (numbered indices),
they are often used to store sorted information.
// What is the last element in the array?
// Assume you don't know the index of the last item
// (do not remove the element (i.e. you can't use pop))
// What is the last element in the array?
// Assume you don't know the index of the last item
// (do not remove the element (i.e. you can't use pop))
// Last occupied index
var lastIndex = students.length-1;
students[lastIndex]; //'Jose'
// What is the last element in the array?
// Assume you don't know the index of the last item
// (do not remove the element (i.e. you can't use pop))
// Last occupied index
var lastIndex = students.length-1;
students[lastIndex]; //'Jose'
// You'll also see this:
students[students.length-1]; //'Jose'
{}
var awesomeStudent = { name: "Julio", enrolled: "Prep +", excited: true, age: 82 };
KEY
VALUE
Objects store properties which are Key-Value Pairs
var awesomeStudent = { name: "Julio", enrolled: "Prep +", excited: true, age: 82 };
KEY
VALUE
anything to the left of the colon will be "stringified"
values can be any JavaScript type
var awesomeStudent = { name: "Julio", enrolled: "Prep +", excited: true, age: 82, speak: function(word){ return word + "!!!!"; }, friends: ["Ruth", "keeevin"] };
var awesomeStudent = { name: "Julio", enrolled: "Prep +", excited: true, age: 82 };
You can add key-value pairs when you define the object like we've done here.
OR
we can add/access key-value pairs with dot or bracket notation.
var student = {};
note: keys are "stringified"
student.name = "Julia";
student // student = { name : ??}
student.name = "Julia";
student // student = { name : "Julia"}
var student = {
name : "Julia"
};
student.name //??
var student = {
name : "Julia"
};
student.name // "Julia"
1 var student = {
2 name = "Julia"
3 };
4
5 var awesomeStudent = student.name;
6
7 awesomeStudent // ??
1 var student = {
2 name = "Julia"
3 };
4
5 var awesomeStudent = student.name;
6
7 awesomeStudent // "Julia"
var student = {};
student.name = "Jonathan";
student // student = { name : "Jonathan"};
student.name = "Jasper";
student // student = { name : ???};
var student = {};
student.name = "Jonathan";
student // student = { name : "Jonathan"};
student.name = "Jasper";
student // student = { name : "Jasper"};
var student = {};
student.name = "Julia";
student.name; //"Julia"
student.location; //??
var student = {};
student.name = "Julia";
student.name; //"Julia"
student.location; //undefined
when you use dot notation, everything after the dot will be interpreted as a string
var awesomeStudent = {};
var newProp = "name";
awesomeStudent.newProp = "Juan";
awesomeStudent // ??
var awesomeStudent = {};
var newProp = "name";
awesomeStudent.newProp = "Juan";
awesomeStudent
//awesomeStudent = {newProp : "Juan"}
With bracket notation there are less constraints...
The most important use cases are if the property name is a variable or a number
It's easy to transform from dot to bracket notation
// with dot notation
student.name = "Julia";
// with bracket notation
student["name"] = "Julia";
// with dot notation
student.name; //"Julia"
// with bracket notation
student["name"]; //"Julia"
The in-memory representation is exactly the same for both
Assignment
Access
var student = {};
Think of dot notation as being shorthand for bracket notation that can only be used when the property name is a string that starts with a letter... it's easier and faster to type
You can imagine that under the hood, the JavaScript engine will take the string that's after the dot and insert it between some brackets.
var student = {};
student. name = "Jose";
var student = {};
student["name"] = "Jose";
var MI6Agents = {};
MI6Agents.007 = "James Bond";
MI6Agents['007'] = "James Bond";
var student = {};
student["name"] = "Jose";
var key = "name";
student[key]; //??
var student = {};
student["name"] = "Jose";
var key = "name";
student[key]; // "Jose"
Dots
strings
Brackets
"strings
"quotes required
"weird characters
other primitives
variables
numbers
quotations
weird characters
expressions
expressions
Dot notation can only be used when the property name is a string that starts with a letter.
Bracket notation must be used when dealing with everything else! Such as variables or numeric property names.
For Loops & Conditionals (if/else)
Execution of code depends on a choice being made as to which path should be followed.
What is Control Flow?
Code rarely runs like this: 1st line, 2nd line, 3rd line, ... last line
Some lines are run more than once (loops)
Some lines are skipped entirely (conditional statements)
useful for when you need to do something for every element in a collection (object or array)
Why are loops important?
Why are if statements important?
useful for when you only want to do something if a certain condition is true
ex: add 10 to every number in an array
ex: if age > 21, add to guest list
There are a few programming constructs that impact the order in which our code is run.
Generally code runs from top to bottom, but when the JavaScript interpreter encounters the following, it gets a bit more complicated...
We'll cover:
... and more interesting!! We able to do more powerful things.
Loops allow us to take a look at each of the properties inside of our objects/arrays
Within the loop, we can do the normal property access and assignment stuff.
Arrays and Objects each get their own special for-loop.
for( var i = 0; i < arr.length; i++) {
//do things...
};
for(var key in obj) {
//do things...
};
Arrays
Objects
Arrays are numerically indexed.
This means you can access the values stored in an array by accessing a numbered position in that array.
var arr = ['pirate','dragon','unicorn'];
for( var i = 0; i < arr.length; i++) {
//this is the body of the loop
//the code in here gets executed once
//for each iteration
};
Index
0
2
1
The code in between the curly braces is called the body of the for loop.
Let's break down the signature of the for-loop the part in between the parens.
var arr = ['pirate','dragon','unicorn'];
for( var i = 0; i < arr.length; i++) {
//this is the body of the loop
//the code in here gets executed once
//for each iteration
}
INITIALIZATION
i is just a number.
The index that we want to start at
(often 0)
var arr = ['pirate','dragon','unicorn'];
for( var i = 0; i < arr.length; i++) {
//this is the body of the loop
//the code in here gets executed once
//for each iteration
}
CONDITION
As long as this is true, we continue with the loop.
Once it is no longer true, the loop ends.
var arr = ['pirate','dragon','unicorn'];
for( var i = 0; i < arr.length; i++) {
//this is the body of the loop
//the code in here gets executed once
//for each iteration
}
FINAL EXPRESSION
This is the amount by which 'i' changes each time the body of the loop is run.
Often we simply increment by 1
var arr = ['pirate','dragon','unicorn'];
for( var i = 0; i < arr.length; i++ ) {
//this is the body of the loop
//the code in here gets executed once
//for each iteration
}
var arr = ['pirate','dragon','unicorn'];
for( var i = 0; i < arr.length; i=i+1) {
//this is the body of the loop
//the code in here gets executed once
//for each iteration
}
All together: we instantiate a new variable i and set it equal to 0, while i is less than the length of the array, we execute the code in the loop body, and then increment i by 1.
for( var i = 0; i < arr.length; i++) {
//body
}
Each iteration of the for loop just executes the code inside the loop body, no matter what that code is.
var arr = ['pirate','unicorn','dragon'];
for( var i = 0; i < arr.length; i++) {
console.log('hi from inside the for loop!');
}
//'hi from inside the for loop!'
//'hi from inside the for loop!'
//'hi from inside the for loop!'
i is just a number, starting at 0 and increasing up to one less than the length of the array.
Remember: arrays are 0 indexed, so the length = max index+1
var arr = ['pirate','unicorn','dragon'];
for( var i = 0; i < arr.length; i++) {
console.log('i: ' + i + ', arr.length: ' + arr.length);
}
//'i: 0, arr.length: 3'
//'i: 1, arr.length: 3'
//'i: 2, arr.length: 3'
How do we use the number stored in the variable i to access the values in the array?
var arr = ['pirate','unicorn','dragon'];
for( var i = 0; i < arr.length; i++) {
var element = arr[i];
console.log(element);
}
//'pirate'
//'unicorn'
//'dragon'
How do we use the number stored in the variable i to access the values in the array?
var arr = ['pirate','unicorn','dragon'];
for( var i = 0; i < arr.length; i++) {
console.log('the valued stored at
the ' + i + 'th position of the array
is: ' + arr[i]
);
}
//'the value stored at the 0th position of the array is pirate'
//'the value stored at the 1th position of the array is unicorn'
//'the value stored at the 2th position of the array is dragon'
Objects are key indexed.
This means you can access the values stored in an object by accessing a key in that object.
var obj = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var key in obj ) {
//do things...
}
The syntax of object for loops isn't like anything else you'll see in JavaScript.
You just have to memorize it.
for( var key in obj ) {
//this is the loop body
}
var obj = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var key in obj ) {
//body
}
Let's break down the pieces.
Specify the object to loop through
var Jade = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var key in obj ) {
//body
}
var Jade = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var key in Jade ) {
//body
}
Create a new variable called key.
For each loop iteration, this variable will hold the value of a property name.
var obj = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var key in obj ) {
//key will be assigned all of the keys in the object
// that is: 'occupation', 'steed', 'bestFriend'
}
for(var key in obj) {
//body
}
All together now: we declare a new variable called key, and tell it which object we're iterating through, then it runs the body of the loop once for each iteration.
var obj = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for(var key in obj) {
console.log('hi from inside obj loop!');
}
//'hi from inside obj loop!'
//'hi from inside obj loop!'
//'hi from inside obj loop!'
The body of the for loop is executed once for each of the keys in the object we're iterating through.
var obj = {occupation: 'pirate',
steed: 'dragon', bestFriend: 'unicorn'};
for( var key in obj ) {
console.log(key);
}
//'occupation'
//'steed'
//'bestFriend'
So what is key on each iteration?
var obj = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var key in obj ) {
console.log(key);
}
//'bestFriend'
//'steed'
//'occupation'
Note: we can't assume that the keys in objects are in any certain order.
Note: we can use any name we want for the variable that will get set equal to all the keys.
var obj = {
occupation: 'pirate',
steed: 'dragon',
bestFriend: 'unicorn'
};
for( var propertyName in obj ) {
console.log(propertyName);
}
//'bestFriend'
//'steed'
//'occupation'
var unitedStatesObj = {rhodeIsland: 'tiny',
alaska: 'untamed', ohio: 'electorally relevant',
california: 'heck yes!'};
for( var state in unitedStateObj ) {
console.log(state);
}
//'rhodeIsland'
//'alaska'
//'ohio'
//'california'
You can use this to be clear about what each property name is.
Generally though, just stick with var key in obj. That's the default and is easy to understand until things get super complex.
var obj = {occupation: 'pirate',
steed: 'dragon', bestFriend: 'unicorn'};
for( var key in obj ) {
var value = obj[key];
console.log(value);
}
//'pirate'
//'dragon'
//'unicorn'
So how do we use these property names to access the values in an object?
var obj = {occupation: 'pirate',
steed: 'dragon', bestFriend: 'unicorn'};
for( var key in obj ) {
console.log('the value stored at ' + key
+ ' is: ' + obj[key]);
}
//'the value stored at occupation is: pirate'
//'the value stored at steed is: dragon'
//'the value stored at bestFriend is: unicorn'
So how do we use these property names to access the values in an object?
LOOPS
for (var i=startIndex; i<arr.length; i=i+increment) { ... }
Order is guaranteed because you are explicitly specifying the indices to check
if('something that will evaluate to true or false') {
//body of the if statement
//this code is only executed
//if the condition is true
}
Also called conditional statements
var alwaysFalse = false;
if(alwaysFalse) {
//this code is never executed
}
var alwaysFalse = false;
if(alwaysFalse) {
//this code is never executed
} else {
//this code is executed if the condition is false
}
if can be followed by else. This ensures that some block of code is always executed.
var alwaysFalse = false;
if(alwaysFalse) {
console.log('code was executed');
console.log('if true');
} else {
console.log('code was executed');
console.log('if false')
}
//'code was executed'
//'if false'
no matter what, one of the two blocks of code is executed because, the thing inside the if parenthesis will be evaluated to be either true or false
if evaluates true, this block of code will be executed
if evaluates false, this block of code will be executed
var temperature = 79;
if(temperature > 80) {
console.log('too hot inside,
party in the streets!');
} else {
console.log('good biking temperature');
}
//'good biking temperature'
var temperature = 79;
if(temperature > 80) {
console.log('too hot inside,
party in the streets!');
} else if(temperature < 32) {
console.log('stay indoors you fools!');
} else {
console.log('good biking temperature');
}
//'good biking temperature'
if can also be followed by else if. This lets you chain together multiple conditions.
'preston' === 'albrey' // ??
8 > 5 // ??
6*2 === 12 // ??
The code inside the parentheses next to if must evaluate to true or false.
Things that evaluate to true or false
var arr = [6,7,8,9,10];
3 < arr.length // ??
arr[2] === 8 // ??
'preston' === 'albrey' // false
8 > 5 // true
6*2 === 12 // true
var arr = [6,7,8,9,10];
3 < arr.length // true
arr[2] === 8 // true
Threequals!!
always use the triple equals sign. double equals do some weird stuff. please don't make me go there keep it easy and just use threequals always.
'hi there' //true
"" //false
undefined //false
[1,2,3] //true
0 //false
-1 //true
1 //true
When evaluating a boolean expression (true or false), JavaScript converts everything to be a true or false value.
These are called 'truthy' and 'falsy'.
var alwaysTrue = true;
var alwaysFalse = false;
alwaysTrue && alwaysFalse //false
alwaysTrue || alwaysFalse //true
// && means both sides must be true
// || means just one side must be true
We can also chain boolean expressions together using && (and) as well as || (or).
var alwaysTrue = true;
var alwaysFalse = false;
!alwaysTrue //false
!alwaysFalse //true
//we can apply the negation operator
//directly to a truthy/falsy value
8 !== 5 //true
'preston' !== 'preston' //false
We can also negate an operator. We can use !== to mean "is not equal to".
function(s){}
DRY!! (don't repeat yourself)
Readability
Why are Functions important?
We use them to control the flow of our program.
var add = function (a, b) {
return a + b;
};
add(1, 2);
declaration / definition
invocation / call time
< Note 'function' keyword
Note > invocation operator ()
var add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
add(1, 2);
body
var add = function (a, b) {
return a + b;
};
add(1, 2);
arguments
parameters
var nameImprover = function (name, adj) {
};
function(item) {
return item * 3;
}
An anonymous function has no name after the 'function' keyword
Often used as arguments to higher order functions
(we'll go into more detail in Part 2)
//Anonymous function saved into a variable
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
//named function
function nameImprover(name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
}
//both work!
Declaring a function is like creating a recipe: you decide what the steps are, but nothing actually gets made.
Invoking a function is like baking that recipe: now that you know what the steps are, you get to actually do them!
The cool part about this is that you can pass in different ingredients to that recipe each time! And each one is run totally independently of all other times that recipe has been created.
//Definition/Declaration:
var breadMaker = function(ingredient) {
return 'fresh baked ' + ingredient + 'bread';
}
//Invocation:
breadMaker('banana nut'); // 'fresh baked banana nut bread'
breadMaker('guacamole'); // 'fresh baked gauacamole bread'
//Putting () next to a function name means
//that you are invoking it right then.
//When we define a function, what that function
// takes in are called parameters
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
//When we invoke a function, what we pass in to
//that particular invocation are called arguments
nameImprover('preston','purple');
var add = function(a, b) {
return a + b;
}
add(1, 2, 3);
Note: the number of parameters and arguments don't have to match
var add = function(a, b, c) {
return a + b;
}
add(1, 2);
c = undefined
if you're curious about how to access arguments with no corresponding parameter look up the "arguments object"
parameters with no corresponding argument are undefined
Why are functions useful?
Definition vs Invocation
Parameters vs Arguments (function input)
//Returned value:
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
//Side Effects:
var instructorName = 'preston';
var sideEffectImprover = function(adj) {
instructorName = 'Col ' + instructorName +
' Mc' + adj + ' pants';
};
//Returned value:
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
var returnResults = nameImprover('preston','purple');
returnResults; //'Col preston Mcpurple pants'
//Side Effects:
var instructorName = 'preston';
var sideEffectImprover = function(adj) {
instructorName = 'Col ' + instructorName +
' Mc' + adj + ' pants';
};
var sideEffectResults = sideEffectImprover('purple');
sideEffectResults; //undefined
instructorName; //'Col preston Mcpurple pants'
var addUserToDatabase = function(username, userObj) {
if(database[username] === undefined) {
database[username] = userObj;
}
};
note that we are not returning anything here.
we don't want to return the entire database and we already have the userObj since we had it to pass into addUserToDatabase. The function is clearly still useful, even though it doesn't return anything.
var totallyHarmless = function() {
return 'world peace';
launchAllNuclearMissiles();
};
totallyHarmless(); //returns 'world peace'
does not invoke launchAllNuclearMissiles because that comes after the return statement and return statements immediately stop the function and end it.
Since a function creates it's own local scope, the global* scope can't see anything that's going on inside that function body.
The return value is the one way for the outside world to 'tunnel into' the function and see something that's going on.
We can use side effects to save the work that a function that has done for us into a variable that's accessible in the global scope.
Or, we can return a value, directly communicating the results to whatever we have in the global scope that's listening for the results of the function.
var testArr = [1,2,3,4];
var globalSum = 0;
var sumFunc = function(arr) {
for (var i = 0; i < arr.length; i++) {
globalSum += arr[i];
}
return 'string from sumFunc';
};
var returnVal = sumFunc(testArr);
console.log(globalSum); //10
console.log(returnVal); //'string from sumFunc'
var add = function(a, b){
return a + b;
};
add(3, 4); // ??
var add = function(a, b){
return a + b;
};
add(3, 4); // 7
Returned Values (function output)
Side Effects
objects {},
arrays [],
function(s){}
{
"name": "Julia",
"location": "Oakland, CA",
"twitter": "@julia"
}
// Object literal
var student = { name: 'Julia'};
// Dot notation
student.location = 'Oakland, CA';
// Bracket notation
student['twitter'] = '@julia';
Objects store information (properties) about a given entity
in memory representation:
{
"0": "Julia",
"1": "Johnny",
"length": "2"
}
// Array literal
var students = [ 'Julia' ];
// Bracket notation for access/assignment
students[0]; //'Julia'
students[1] = 'Johnny';
// Dot notation for native properties
students.length; //2
Arrays store collections of values
in memory representation:
Why can't we use dot notation for these?
{
"0": "Julia",
"1": "Johnny",
"length": "2"
}
Arrays are special objects
in memory representation:
var treasureChest = function(){
return "you can't get nothin' from me!";
};
treasureChest.treasureMap = 'twirl three times';
console.log(treasureChest.treasureMap);
//'twirl three times'
Anything we can do with an object, we can do with an array and function.
Examples:
Add a property to it (not super useful)
Assign a variable to point to it
Overwrite a variable with it
Pass it in as an argument to a function
Return it as a value from a function
var box = {};
box.innerBox = {};
var box = { "innerBox" : {} }
var box = { "innerBox" : { "innerInnerBox" : {} } }
var box = {};
box.innerBox = {};
box.innerBox.innerInnerBox = {};
box //??
var box = {};
box.innerBox = {};
box.innerBox.innerInnerBox = {};
// or...
box['innerBox'].innerInnerBox = {};
// or...
box['innerBox']['innerInnerBox'] = {};
var box = {};
box.innerBox = {};
box.innerBox.innerInnerBox = {};
var box = {};
box.innerBox = {};
box.innerBox.innerInnerBox = {};
// or...
box['innerBox'].innerInnerBox = {};
var box = {};
box.innerBox = {};
box.innerBox.innerInnerBox = {};
// or...
box['innerBox'].innerInnerBox = {};
// or...
box['innerBox']['innerInnerBox'] = {};
// or...
var box = {
innerBox : {
innerInnerBox : {}
}
};
{ "innerInnerBox" : { "full" : true } }
var box = {};
box.innerBox = {};
box.innerBox['innerInnerBox'] = {};
box.innerBox.innerInnerBox.full = true;
var myInnerBox = box['innerBox'];
myInnerBox; //??