Day 3: Arrays and Objects

Wednesday, June 28, 2017

Lecture Videos

Morning:

Playlist | Day 3, Part 1

Afternoon:

Playlist | Day 3, Part 1

Topics

Arrays

Objects

  • Object literals
  • Property Naming
  • Retrieving property values
  • Setting property values

Handling exceptions

  • try
  • catch
  • finally

this

  • default binding through function invocation
  • implicit binding through method calls
  • explicit binding with .bind

Foundation

  • The grid system
  • Responsive design (adjusting style based on window size)
  • Foundation Docs

Markdown

Examples

Arrays

Arrays are extremely useful data structures in JavaScript, as they can be easily iterated and transformed through methods like map, filter, and reduce. Sometimes, you may have an ‘array-like’ collection (like a NodeList or function arguments) that you would need to convert to an actual Array before you could use these methods. This can be done using Array.from



let paragraphs = document.querySelectorAll('p')
paragraphs.map((p) => {
  p.textContent = "This won't work because paragraphs is a NodeList, not Array!"
})
// => Uncaught TypeError: paragraphs.map is not a function

let actualArrayOfParagraphs = Array.from(paragraphs)
actualArrayOfParagraphs.map((p) => {
  p.textContent = "This totally does work because we created an Array from our NodeList!"
})


Requirements for 'Array.from'

What objects can you convert to an Array using ‘Array.from’?

  • Any array-like object with a ‘length’ property and indexed elements
  • Iterable objects (like Map or Set)

For more info, check out this article on MDN.

Objects

Almost everything in JavaScript is an Object. The easiest way to create new Objects is with the object initializer, more commonly known as ‘object literal’ syntax. Basically, use curly braces to make an object {} and fill in the properties that you want.

Objects contain key/value pairs that allow you to set and retrieve values from them.



// create a new object and assign some properties
const myObject = {
  prop1: 'Hello there',
  prop2: 42
}

// access the values in several ways, usually 'dot' or 'square bracket' notation
myObject.prop1 // => 'Hello there'
myObject['prop1'] //=> 'Hello there'

// new key/value pairs can also be assigned with these notations
myObject.prop3 = 'New Value!'
myObject['prop4'] = 'Newest Value!'

console.log(myObject)
// { 
//   prop1: 'Hello there',
//   prop2: 42,
//   prop3: 'New Value!',
//   prop4: 'Newest Value!'
// }


We know that we can iterate through an Array using map or forEach. Can we do something similar with objects? There are a few ways to do it, but one of the newest and easiest is the Object.keys method. It iterates through the enumerable properties of an object, returning an array of the property keys. Once we have an array of keys, we can map over that and access each of the object properties individually.



const myObj = {
  a: 'hi',
  b: 42,
  c: [1, 2, 3]
}

const myObjKeys = Object.keys(myObj)    // ['a', 'b', 'c']

myObjKeys.map(key => myObj[key])        // ['hi', 42, [1, 2, 3]]


Handling exceptions

In JavaScript (as in many languages), there is a way to ‘try’ a block of code that may produce an exception, and if it does produce an exception, ‘catch’ it and execute a different block of code. The catch block receives the exception as an argument. There is also an optional ‘finally’ block, which will always run, regardless of whether there was an exception.



try {
  // try running this code first
  somethingThatMightBlowUp()
} catch (e) {
  // executes if the 'try' block produced an exception
  logMyErrors(e)
} finally {
  // always executes after the previous blocks have run
  console.log("Done!  Maybe there was an exception, maybe there wasn't.")
}


For more info, read this MDN article.

this

The same function can have different values for this depending on how the function is called/invoked.

Try this example live on CodePen.



const app = {
  sayYeah() {
    console.log(`Yeah, ${this}`)
  },
  
  toString() {
    return 'app object'
  }
}

// When invoked as a method
app.sayYeah() // "Yeah, app object"

// When invoked as an event handler
document
  .querySelector('button')
  .addEventListener('click', app.sayYeah)
  // "Yeah, [object HTMLButtonElement]"

// When manually set with bind
app.sayYeah.bind('w00t')() // "Yeah, w00t"


Foundation

Foundation is a CSS (and JS) framework that makes it easy to create stylish, responsive web pages. The foundation (get it?) of it is the grid system. The grid splits the page into 12 equally-sized columns, making it easy to set the alignment of elements on the page by specifying how many columns they span.

In addition, you can add sizes of ‘small’, ‘medium’, ‘large’, etc, to specify different behavior at different screen sizes. In the following example, the two child divs will be full screen width at small screen sizes (stacked on top of each other), and half of the screen width at medium and larger screen sizes (appearing next to each other).



<div class="row">
  <div class="small-12 medium-6 columns">
  </div>
  <div class="small-12 medium-6 columns">
  </div>
</div>


Projects

Person Stats

Final Version

Homework

  • Store the flicks in an array, as well as in the DOM.

Bonus Credit

  • Add a fav button to each list item.
  • Make it change the appearance of that item (e.g. Add a background color.)

Mega Bonus Credit

  • Add a remove button to each list item.
  • Make that button actually work.

Super Mega Bonus Credit

  • Make sure that both of those buttons affect the array as well.
  • Make the fav button toggle the fav status.

Super Mega Bonus Credit Hyper Fighting

  • Add buttons that move a flick up and down the list.