Initial problem with static values

To continue our colors example, let's say we want to create a function that takes our object and gets the color according to the key provided.

Since we're getting a color, we'll appropriately call this function getColor:

const colors = {
  blue: "#f00",
  orange: "#f60",
};

function getColor() {}

And it's going to take a key and retrieve the color value associated with the key. How would we do that?

See if you can do this on your own...

So as we mentioned, getColor will accept a key, so we'll call the parameter itself key:

function getColor(key) {}

Then it's going to take the colors object, and using the key, return that key's associated value. So first to get our data, we need to take the colors object and use the dot syntax to get the value, we say colors.key. And finally return it:

function getColor(key) {
  return colors.key;
}

Simple enough. So let's try finding the color with the key blue. So we'll pass it in as a string and console log the result:

console.log(getColor("blue"));

[Run code] But strangely enough. We get undefined. It couldn't find a key with the name blue. Why is this? That's what we're going to set out to figure out in this lesson. We're going to do a much deeper dive into working with properties as well as how to use them in a traditional static way or a more dynamic way, as in this case.

[Objects]

So right now, we have a simple object with three key-value pairs.

const colors = {
  yellow: "#ff0",
  blue: "#f00",
  orange: "#f60",
};

Here all of these pairs were created directly on the original object itself.

We know that we can access values from the object according to their key after the object was created:

console.log(colors.yellow); // "#ff0"

And we can also change our object data after it was created as well, using a very similar syntax.

Let's say we want to add a new property onto our object, red. So we can use the same dot syntax with this new key that we want to add by saying colors.red:

colors.red;

And then we can directly change the object, also known as mutating it, to have it include its associated value. We do that by adding an equals operator, just like we would if we were making a variable with the name red. So let's say red is equal to the string #f00:

colors.red = "#foo";

And to see that red was added, we can just log colors:

console.log(colors);

[Run code] And we see that it was added.

Oh, but oops. I made a small typo. Instead of including the value '#f00', I set red to the value '#foo'.

No worries. The process of updating associated values is as easy as setting new ones. We can just use the same key reference and set it equal to the correct value, like so:

colors.red = "#f00";

console.log(colors);

[Run code] And when we run this code, our update was applied and the existing key was overwritten with the new value.

So be aware that values on an object can change or updated at any time after the object is created and we have a reference to it, all with the familiar dot syntax.

The dot notation works great if we are working with static values. That is, we know the key that we want to create or perform an update to ahead of time. And most of the time, the dot notation is the most comfortable way to immediately get or modify values.

We're going to move onto another alternate way to access and update key values pairs in objects, but before we do, we need to look at another interesting feature about objects that isn't immediately apparent.

As we mentioned in the first video, object keys are just strings. So as long as we have a valid string, we should be able to add it as a key, correct?

Let's take a look at our original colors object once again. And note that all of the keys are composed of one word each:

const colors = {
  yellow: "#ff0",
  blue: "#f00",
  orange: "#f60",
};

In most cases, you're going to write your property names just like this, as simple, single words. If you need to be more specific, we often use the camel case convention for property names, too. For example, if we wanted yellow to be yellowColor for some reason, it would be written properly like so:

const colors = {
  yellowColor: "#ff0",
  blue: "#f00",
  orange: "#f60",
};

But what if we wanted to add yellow Color as a key but with two separate words with a space in between the words like so:

const colors = {
  yellow Color: "#ff0",
  blue: "#f00",
  orange: "#f60"
};

Take a minute, think critically about the nature of keys and see if you find a way to add keys that have spaces in between words...

Did you figure it out? Well, if you tried to directly create a new object with yellow Color, like we have here, you would get an error

[Run code] Namely this error saying unexpected identifier, because it's not been provided as a valid property.

If you tried using the dot notation to directly mutate the object, like so:

colors.yellow Color = '#ff0';

[Run code] You'll get the same error. However, we can add whatever property we like to objects as long as they are a valid string, therefore, they can include spaces. All we have to do is just include quotes around the key, any type of quotes:

const colors = {
  "yellow Color": "#ff0",
  blue: "#f00",
  orange: "#f60",
};

And if we log it:

console.log(colors);

[Run code] We see the added property with no errors. But this raises a question. If we couldn't use dot notation to add it to the object, how can we retrieve the value of yellow Color without dot notation?

For this, we have an alternate syntax for getting and modifying properties that we can use with objects--the square brackets notation.

As it's name indicates, to get any keys value. We take the object, add a set of square brackets around it, and add the key name as a string that we want.

So to do that for our yellow Color property, we take our colors object, add square brackets, and add the key name as a string:

console.log(colors["yellow Color"]);

[Run code] And we get it's value.

So this alternate syntax is neat, but who cares? Well what's interesting about it is that it gives us the capability of using keys dynamically, where for example, the key we want to access is based on a variable that can change.

So let's say that, for example, we want other people using our app to be able to add their own colors to this object with their own hex codes.

In the past, we would have no way of doing that. Why? Because using the dot notation, the key has to be known beforehand. It can't be provided as a variable. But with square brackets notation, it can be.

So now, within our code, we can dynamically let users provide whatever color and hexcode they want to our colors object. So first we'll store the name of the color the user provide, and let's say that they provided the string green:

const color = "green";

And another variable to store the corresponding hexCode they provide, called hex code with the value 0f0:

const hexCode = "#0f0";

And now, what do we have to do in order to add both of these values to our colors object. Take a minute and see if you can figure this out on your own.

We can take the line where we logged yellow Color, remove the log:

colors["yellow Color"];

And instead of providing a static string here, we can drop the strings, and use a variable and then provide our color variable to include as the new key for the color the user will be adding.

colors[color];

And then we'll set that to the hexCode variable to associate the two and at the end we'll log the updated colors object:

colors[color] = hexCode;
console.log(colors);

Now let's run this. [Run code]

And in our final colors object, green is added with the hex code. Excellent.

But in fact, we can make this even simpler. Instead of mutating the object with the new key-value pair after the object was created, we can simply add it directly on the object as it is initially made.

So let's comment out what we just added and include directly on the object a set of square brackets around color, and note that this is perfectly valid to do. And then after the colon, set it to our hexCode variable:

const colors = {
  "yellow Color": "#ff0",
  blue: "#f00",
  orange: "#f60",
  [color]: hexCode,
};

// colors[color] = hexCode;
console.log(colors);

And if we add another color, say black, with hex code #000, [Run code], it should be added to our object just like before.

Solving original problem with square brackets notation

So the square brackets notation is the way to dynamically get and update object keys and values based on changing data.

And now that we have this new capability, we can finally solve our original problem with the getColor function.

Give it a shot one more time and see if you can resolve our initial problem in getting a specific keys value...

So now all we have to do is replace the dot notation of colors.key with colors square bracket key and return it. And if we console log what we get when we pass in the key green

function getColor(key) {
  return colors[key];
}

console.log(getColor("green"));

[Run code] We get the hex code of the color our user just added.

Deleting properties

And finally, for the sake of completeness, since we've covered dynamically, getting, creating, and updating object values, we should cover how we need to delete a property if we want it as well as it's value to be removed from our object entirely.

To remove a property, we can use delete operator. So ultimately, if we wanted to delete both of our recently added properties, we could say with the dot notation:

delete colors.green;
console.log(colors);

And when we run this [run code] our object is mutated to remove the pair associated with the key green.

But alternately, we can use the square brackets syntax with a variable. Say if we had a variable named colorToDelete set to the string black:

const colorToDelete = "black";

We could then say:

delete colors[colorsToDelete];
console.log(colors);

[Run code] And this works perfectly fine, too.

Review

So in summary, be aware of the static nature of objects. Many times you'll rely on dot notation, especially for getting data and calling methods. But be aware that to use it, you must know the property name ahead of time and it can't change. If you have keys that can change as your program runs, be sure to use the square bracket notation.