As a JavaScript developer, you'll frequently find yourself retrieving properties from objects. Both manual and programmatic navigation through complex object structures are crucial preliminary tasks, often undertaken before diving into the core logic of your applications.
Having already gained a basic understanding of what an object is, how to create one, and the methods to access its values, this lesson aims to delve deeper into accessing properties. We'll explore intricacies and techniques for referencing values from objects, enhancing your ability to interact with these fundamental JavaScript structures.
How to Reference JavaScript Object Properties
Understanding how to access properties in JavaScript is crucial, and there are two primary methods for doing so: dot notation and square brackets. To gain a deeper insight into these methods, especially in the context of more complex objects, consider the following example, which resembles a user profile structure:
const currentUser = {
firstName: "John",
lastName: "Doe",
age: 30,
emails: ["[email protected]", "[email protected]"],
locations: [
{
address: "123 State St",
city: "Scranton",
state: "PA",
zip: "12345",
},
{
address: "500 Paseo de Vermut",
city: "Bilbao",
country: "Spain",
},
],
greeting: function () {
console.log(`Hey, ${this.firstName}!`);
},
"is Authorized": true,
};
This object has a lot going on, and in the following sections, you'll be exploring how to reference it's properties effectively.
Accessing Properties With Dot Notation and Bracket Notation
To access the basic properties of currentUser, such as firstName, lastName, and age, you can use dot notation (currentUser.firstName) or bracket notation (currentUser["lastName"]). Dot notation is more succinct but requires the property name to be a valid identifier (no spaces, no special characters).
currentUser.firstName; // "John"
currentUser["firstName"]; // "John"
currentUser.is Authorized; // Uncaught SyntaxError: Unexpected identifier 'Authorized'
currentUser["is Authorized"]; // true
As you can see in the example above, dot notation is neater but has its limitations. Bracket notation is needed when the object key has characters which would make it an invalid identifier.
Bracket notation also offers flexibility --- namely, the ability to dynamically get object properties:
let lastNamePropertyKey = "lastName";
currentUser.lastNamePropertyKey; // undefined
currentUser[lastNamePropertyKey]; // "Doe"
currentUser["last" + "Name"]; // "Doe"
As you can see in this example, with bracket notation, you can set the property key to a variable, which you can then stick inside the square brackets. Everything inside the square brackets is evaluated, so the lastNamePropertyKey evaluates to the string "lastName", which fetches the corresponding string from the object.
Since everything in the square brackets get's evaluated, you can include any kind of expression there too, such as the concatenation (with +) of two separate strings to construct the property key.
Accessing Nested Data Structures
The emails property demonstrates an array within an object. To get at a certain email, you'll need to first access the array, and then access an email using square bracket notation with an index number, like you do with arrays:
const currentUser = {
// ...
emails: ["[email protected]", "[email protected]"],
// ...
};
currentUser.emails[0]; // "[email protected]"
currentUser["emails"][0]; // "[email protected]"
currentUser.emails.0 // Uncaught SyntaxError: Unexpected number
You'll note that you can still use dot notation or bracket notation for the object keys, but you can only use square bracket notation for arrays. 0 on it's own is not a valid JavaScript identifier, after all.
Interestingly, you can reference an array position with a string:
currentUser.emails["0"]; // "[email protected]"
This works because JavaScript arrays are actually special kinds of objects. When you use a string to reference an array index, JavaScript internally converts that string to a numeric index. This is the same with regular objects:
currentUser["1"] = "Set as a string key"
currentUser[1]; // "Set as a string key"
currentUser[2] = "Set as a numeric key"
currentUser["2"]; // "Set as a numeric key"
As you can see, even though currentUser is a regular object, and not an array, it also converts strings to integers if it's able to.
Arrays in JavaScript are essentially objects with properties named in an ordered, numeric fashion. It behaves differently from a regular object, though, for instance, when you assign a value to an index number (pads out the space with undefined).
Expanding further, arrays can also have properties that are not numeric indexes:
let array = [1, 2, 3];
array["property"] = "value";
In this example, a non-numeric property property is added to the array. This doesn't change the length of the array because the .length property of an array only accounts for elements with numeric indexes. However, it illustrates how arrays in JavaScript can hold more than just sequentially indexed elements, behaving like objects. Whether this is a good idea, however, is up for debate!
The locations property in the currentUser object is an array of objects, each representing an address. Accessing these nested objects involves specifying an index for the array, followed by the property name of the nested object:
const currentUser = {
// ...
locations: [
{
address: "123 State St",
city: "Scranton",
state: "PA",
zip: "12345",
},
{
address: "500 Paseo de Vermut",
city: "Bilbao",
country: "Spain",
},
],
// ...
};
currentUser.locations[0].city; // "Scranton"
currentUser["locations"][0].city; // "Scranton"
currentUser["locations"][0]["city"]; // "Scranton"
As you can see, no matter how nested things get, you just have to know what kind of data structure you're resolving to, and then you need to use the appropriate notation for that data structure. In this case, for currentUser you can use dot or bracket notation. When you access locations, then you need to use square bracket notation because it's an array. When you access an element inside locations, then you can use dot or bracket notation because it's an object again.
This type of nesting is typical of objects that you'll see in the wild.
Object Methods and the this Keyword
The currentUser object also demonstrates more advanced features of JavaScript objects, including methods:
const currentUser = {
// ...previous properties...
greeting: function () {
console.log(`Hey, ${this.firstName}!`);
},
// ...
};
currentUser.greeting(); // "Hey, John"
currentUser["greeting"](); // "Hey, John"
As you can see, you can access a method in the same way you can access any other propety. Once you have accessed the method, you then call the method with () and any arguments it may have. In this case, you don't need any arguments.
The greeting property is a function that acts as a method of currentUser object. It uses the this keyword to reference other properties of currentUser. When you call currentUser.greeting(), it accesses this.firstName within the function, effectively referring to currentUser.firstName.
The keyword this in the context of this code refers to currentUser, making it equivalent to currentUser.firstName. However, using this offers flexibility as it always refers to the object the method is a part of, regardless of the variable name the object is assigned to.
You won't go into any more depth on the this keyword in this lesson, as it's quite a deep subject and you don't need to worry about it at this stage in the course.
Objects Assigned to Variables
One final thing to note about accessing properties within objects is that objects are assigned to variables by reference, and so they behave differently than primitive values, such as strings:
let john = {"name": "John"};
let polly = john;
polly.name = "polly";
polly; {"name": "polly"}
john; {"name": "polly"}
As you can see, both variables john and polly point to the same object. If you want to keep two distinct objects, you need to make sure that you create a new object each time.
Summary: How To Reference Object Properties
This article explores the essential techniques of accessing properties in JavaScript objects, a key skill in JavaScript development.
- Use either dot notation or bracket notation to access properties in a JavaScript object, with dot notation for straightforward cases and bracket notation for properties with special characters or dynamic names.
- Access array elements within an object using bracket notation, as array indexes need to be numeric.
- Access properties in nested structures, such as arrays of objects, by layering dot and bracket notation as needed.
- Methods (functions within objects) use the
thiskeyword to reference the object they belong to. - Objects are assigned to variables by reference, which can lead to unintuitive results