Intro to JavaScript Objects
Learning Objectives
Students Will Be Able To:
- Describe the Use Case for Objects
- Create Objects Using Object Literals
- Add a Property to an Existing Object
- Modify the Value of a Property
- Explain When to Use Dot or Square Bracket Notation
- Delete a Property
- Iterate Over an Object's Properties
- Use Property Shorthand Syntax
- Identify when a Property is a Method
- Describe How a Variable References an Object
Roadmap
- The What and Why of Objects
- Ways to Create Objects
- Creating Objects with Object Literal Notation
- Properties - Review Questions
- Adding Properties to an Existing Object - Dot Notation
- Adding/Updating Properties - Practice
- Accessing Properties with Square Bracket Notation
- Square Bracket Notation - Practice
- Checking if an Object has a Property
- Deleting a Property
- Iterating Over an Object's Properties
- Property Shorthand Syntax
- Methods
- How Variables Reference an Object
- Essential Questions
- Further Study
Lesson Setup
For this lesson, we're going to code along using an HTML, CSS & JS
REPL
from repl.it -- you can name it "JavaScript Objects Practice"
.`
What Are Objects?
- Objects are the most common data structure in Object Oriented Programming (OOP)
- Very simply, objects are a collection of zero or more properties
-
So what's a property? A property consists of a key: value pair, where the:
- key is a string (JS will coerce the type automatically), and the
- value is any JS expression (code that evaluates to a single value or thing), including other objects (yes, functions too)
-
In computer science, collections of key/value pairs are commonly referred to as dictionaries - a good visualization of what an object is
Why Objects?
- In OOP, we often model the goal of our application using real-world objects
- As web developers, you'll be working with objects more than anything else
-
The following is just a small example of what is modeled using objects:
- The browser window and the elements it visualizes are all represented in memory as JS objects
- Every part of those elements, including their styling, is accessed via JS objects
- Data submitted from the browser will be accessed on the server as objects
- Data retrieved from a database will be stored in objects
- Even primitive data types like strings and numbers are turned into an object on demand by the JS runtime when we want to call a method like
toUpperCase
! BTW, this process is called boxing. - Now does it make sense why it's called Object Oriented Programming?
Ways to Create Objects
-
There are three different ways we can create objects:
- By using Object Literal notation
- By invoking a Class (also known as aConstructor Function)
- By using the
Object.create
method
- Today, we're going to focus on using Object Literals to create objects
- Later, we'll learn how Classes are used
- Using
Object.create
is not very common and won't be used during SEIR, but as always, you're encouraged to research it
Creating Objects with Object Literal Notation
-
Now let's create an object by using Object Literal notation, also known as an Object Initializer:
const game = {}; console.log(typeof game); // "object"
Creating Objects with Object Literal Notation
- As you can see, Object Literal notation consists of a set of opening and closing curly braces,
{}
- We just used curly braces to create an empty
game
object. We consider it to be empty because it contains no _? -
Let's change the code so that
game
has a property:const game = {title: 'Guess the Number!'}; console.log(game);
- Stylistically, defining an object with a single property or a couple of "short" properties on a single line of code like this
let point = {x: 10, y: -5};
isn't a problem (unless it is with your boss) - It's all about maintaining readability
-
Properties are separated by commas:
const game = { title: 'Guess the Number!', biggestNum: 100 };
-
Syntactically, trailing commas are permitted (in arrays too):
const game = { title: 'Guess the Number!', biggestNum: 100, };
Properties - Review Questions
-
Considering:
const game = { title: 'Guess the Number!', biggestNum: 100, };
-
Let's answer the following questions:
- How many properties does
game
contain? - What are the keys (AKA property names)?
- What are the property values of
game
? - What are the data types of the keys?
- How many properties does
Adding Properties to an Existing Object Using Dot Notation
-
There are two different syntaxes available to access, add or modify an object's properties:
- Dot notation, and
- Square Bracket notation
- We'll discuss why there are two syntaxes in a bit, for now, let's use dot notation to add another property to the
game
object:
game.smallestNum = 0;
- Using the assignment operator, if a property doesn't exist, it is created, otherwise it's updated.
Adding/Updating Properties Practice (3 min)
-
Using dot notation on the
game
object:- Add a property with a key of
numGuesses
set to a value of0
- Update the
smallestNum
property's value to be1
- Add a property with a key of
Accessing Properties with Square Bracket Notation
- The other way to access, add, update and delete properties is by using square bracket notation
- We use square bracket notation instead of dot notation when at the time you're writing the code, you don't know which property needs to be accessed
- In other words, we use square brackets to access properties dynamically during runtime
Less common is to have to resort to using square brackets to access properties when the key name contains a space.
Square Bracket Notation
-
Square bracket notation has the following syntax:
someObject[<any JS expression>]
- For example to access the
game
object'stitle
property, we could write this code:
console.log(game['title']);
Please note: The above example is just a way to demonstrate the syntax. More efficient code would be console.log(game.title);
- If the result of the expression between the brackets is not a string, JS will convert it to one. For example:
const weirdObj = {};
weirdObj[null] = true;
console.log(weirdObj) // {'null': true}
- Again, the expression between the square brackets can be any expression - even a function call!
Square Bracket Notation - Practice
-
Consider an object that represents a catalog of items where:
- Each property in the object represents an item for sale
- The key of each property represents the item's SKU (Stock Keeping Unit - a retail store's unique ID for an item)
- The value of the property represents the price of the item
- For this practice activity we're going to create another object named
catalog
that includes a few items - but don't delete yourgame
object. - Again, each item is a property with it's key set to a unique alphanumeric string (a SKU) and its value to a number representing its price
- Note: If you want to include special characters in the key, just be sure to use quotes
-
Now let's code a price lookup loop:
let sku = ''; while (sku !== 'quit') { sku = prompt('Enter SKU or "quit" to exit: '); let price = catalog[sku]; if (sku !== 'quit') alert(`The price of ${sku} is ${price}`); }
- That string in the
alert
is called a template literal and is delimited using back-tick characters (it's above the tab key). One of its benefits is that we can use string interpolation to embed the results of JS expressions right into the string using the${<exp>}
syntax!
Checking if an Object has a Property
- Notice that if we enter a non-existing SKU (key), we are alerted a price of
undefined
- Unlike when we try to access an undeclared variable, we don't receive an error when we access a property that doesn't exist. Instead,
undefined
is returned - nice! - However, we can't rely on a value of
undefined
to check if a property exists because maybe a property legitimately has a value ofundefined
- Instead, we can use the
in
operator... -
Let's tweak the code to use the
in
operator to check if the user has entered a valid key (SKU):let sku = ''; while (sku !== 'quit') { sku = prompt('Enter SKU or "quit" to exit: '); if (sku in catalog) { let price = catalog[sku]; alert(`The price of ${sku} is ${price}`); } else if (sku !== 'quit') { alert('Invalid SKU - try again'); } }
- Nice!
Deleting a Property
-
To completely remove a property from an object, we use the
delete
operator:const geniuses = { Jemison: true, Hopper: true, Einstein: true, McNair: true, Lovelace: true, carrotTop: false }; // see ya! delete geniuses.carrotTop;
- Try it out! Use the
delete
operator to remove one of the items from yourcatalog
object
Iterating Over an Object's Properties
- Before continuing to work with the
game
object, comment out the price lookup code... - We often need to iterate over an object's properties
-
We can iterate over the keys of the properties using a
for...in
loop:for (let key in game) { console.log(`The value of the ${key} property is ${game[key]}`); }
-
There's a couple of nifty ES2017 methods that can be used to iterate over the keys & values of an object's properties:
- Although cutting edge, these static methods have already been implemented in all modern browsers
-
Each of those methods mentioned returns an array that we can iterate over, for example:
Object.values(game).forEach(function(val) { console.log(val); });
Note: The ECMAScript specification does not dictate how properties should be ordered, however, all browsers currently iterate over them in the order they are defined/added.
Property Shorthand Syntax
-
It's a common scenario to want to pass the values of variables as properties (having the same name as the variable) in an object:
const latitude = getLat('Disneyland'); const longitude = getLng('Disneyland'); const location = { name: 'Disneyland', latitude: latitude, longitude: longitude };
- ES2015 strikes again...
-
Thanks to ES2015's Property Shorthand syntax, we can now do this
const latitude = getLat('Disneyland'); const longitude = getLng('Disneyland'); const location = { name: 'Disneyland', latitude, longitude };
- Again, note how the variable name determines the name of the property
Methods
- When a property holds a function, we commonly refer to it as a method of the object
-
Let's add a
play
method to thegame
object:game.play = function() { this.secretNum = Math.floor(Math.random() * (this.biggestNum - this.smallestNum + 1)) + this.smallestNum; }
- Try it out in the console by calling
game.play()
and then checking the value ofgame.secretNum
a few times - What's with the
this
... - The
this
keyword represents the "context" of a function - In this case,
this
is set by JavaScript to be the object the method is called on - We'll have a dedicated lesson on
this
- IMPORTANT: Due to how
this
is set within arrow functions, it's best to avoid using them as methods in objects
How Variables Reference an Object
- As you know, variables are slots in memory that hold a value
-
All non-object data types are known as primitive, or value, types because they hold a single value. Picture a table in memory like this:
var | value - let x = 25 --> x | 25 var msg = 'hello' --> msg | 'hello'
- But objects are complex/reference types because they can hold multiple pieces of data...
-
Objects, including Arrays, Functions, etc. are stored in a separate part of memory known as the heap. A variable for an object has as its value a "reference" (think pointer):
var | value/ref - let x = 25 --> x | 25 var msg = 'hello' --> msg | 'hello' HEAP const obj = {a: 1} --> obj | ref1 > {a: 1} <-| let arr = [1,2] --> arr | ref2 > [1,2] | let obj2 = obj --> obj2| ref1 -
- Interestingly, the elements of an array and the properties of an object hold their values in the same way!
Now this all makes sense:
const arr1 = [];
const arr2 = [];
const arr3 = arr1;
arr1 === arr2 // false!
arr3 === arr1 // true!
Essential Questions
❓ An object is a collection of zero or more ___.
❓ Properties are _: __ pairs.
❓ Is it more efficient to access properties via dot or square bracket notation?
❓ What type of for
loop is used to iterate over the keys of an object?
❓ Is the following valid code?
const name = prompt('Enter your name: ');
const age = prompt('Enter your age: ');
const person = {name, age};
Further Study
- getter and setter properties allow you to treat methods like regular properties that you can access without invoking and set using the assignment operator (
=
) - Computed Property Name syntax allows for an expression to determine the key name inside of an object literal - just like using square bracket notation on an existing object