9.1: JavaScript Objects
Last updated
Last updated
By the end of this lesson, you should be able to:
Explain what an Object is in JavaScript.
Explain when and why to use an Object datatype.
Explain the differences between Objects vs Arrays.
Declare an Object using JavaScript syntax.
Access, add, or replace attributes in an Object.
In this module we will introduce a new data structure called the JavaScript Object. This data structure is called different names in different contexts. For example, JS Objects are known as "hash tables" in computer science, "dictionaries" in Python, and "HashMaps" in Java. The JS Object is *not* the same "object" concept referred to in Object Oriented Programming.
We will use Objects to implement card games. It turns out that cards are easily represented by Objects and a clear demonstration of why Objects can be useful.
What would be the best way to represent a deck of cards in code? A deck of cards is a set of data (cards) that is of the same type (each card has the same attributes). This implies an array. We could create an array like the following.
Is this a good representation of a card deck? Let's think abstractly about what attributes belong to a card deck.
A deck of cards is implicitly ordered. An array was a good choice to represent this.
Each card has a rank. Our array of strings stores this rank in the sub-strings "nine", "ten", or "jack". Card ranks have order that we do not represent in our strings, e.g. queen > jack
.
Each card has a suit. Our array of strings stores this suit in the sub-string "hearts".
How would we obtain rank and suit attributes of cards in our deck? In our above example, we could perform string manipulation to extract rank and suit values, but we would subsequently also have to write logic to compare rank strings to determine card order. Let's see if we can represent card attributes in a more convenient manner.
Objects are perfect for representing single units of data (e.g. cards) that themselves contains smaller units of data that are attributes of the larger unit. The attributes of an Object need not be the same data type- they can be any data type, and each attribute can have its own data type. The following example is an Object representation of a single playing card.
The example encodes 3 attributes of a playing card. rank
is a number to facilitate comparison with other cards. suit
is still a string but now easily accessible without string manipulation. name
is used for display purposes, to quickly convert the rank
number into a string. This is especially helpful for face cards whose names are not the English word of the rank
number.
We can use the .
operator to access Object attributes. In the following code snippet, we access each of the playingCard
Object's attributes with the .
operator. We can also access Object attributes using []
notation, but this will typically not be necessary.
We can combine objects and arrays to store more complex data types, such as a deck of cards. Each card is represented by an object, and the set of cards is represented by an array.
Given the above card deck representation, we can use a loop to access all cards in a deck.
Inside the loop we can access a specific card's attributes using dot notation on that card's object in the array.
When should we use Objects versus Arrays? Here is a summary.
We can shuffle elements in an array by swapping random elements in the array repeatedly. We can apply this concept to shuffling cards, where each element in a card deck array is an object representing a playing card. The following code simulates card shuffling and will be useful for the card games we will implement.
High Card is a card game where each player draws a random card, and the player with the highest card wins. Below is a sample implementation of High Card. We will soon be creating other card games, combining all we have learned so far in SWE Fundamentals.
In the following implementation, we use the JS array pop
method to draw a random card from the deck. pop
removes and returns the last array element (i.e. draws a card from the top of the deck). We can rely on pop
to draw a random card because the deck is already shuffled.
After drawing cards, we can use the cards' rank
attributes to compare which is higher.
1 acceptable way to initialise a standard 52-card deck in our code is to hard-code it, i.e. manually specify each card and each of its attributes in code. Use this hard-coded deck for this module's exercises below.
Implement the High Card code above to get a working High Card game.
Change the High Card program so that the player and computer each draw 2 cards instead of 1. The player with the highest of any of the cards wins.
myObj.name
vs myObj[name]
vs myObj['name']
myObj.name
and myObj['name']
are equivalent.
myObj[name]
returns the value that corresponds to the key with the value stored inside the variable name
. For example, if we declare var name = 'Luke';
, then myObj[name]
is equal to myObj.Luke
.
We cannot use .
notation for numbers. For example, for an object key with value '1'
, we cannot do myObj.1
. We must do myObj[1]
or myObj['1']
, where JS auto-converts 1
in the former example to '1'
since object keys can only be strings.
Objects | Array | |
---|---|---|
Is the data ordered or unordered?
Unordered
Ordered
What kind of data is stored inside?
Attributes that represent different types of data, e.g. colours, suits, and ranks for cards.
Elements that are all the same type of data, both in terms of data type (e.g. boolean, number, string, Object, Array) and data meaning (e.g. all elements are cards)
What operations do you want to do on this data?
Access a single piece of the data: card.rank
card.suit
Do the same operation to every piece of data you have (in a loop).