TOC
Objects:

Properties

In the previous article, where we introduced you to the concept of objects, we saw an example of how an object could hold one or several properties. In this article, I want to dig much deeper into the concept of object properties and how they can be used.

Properties are like variables: They are declared with a name, and used to contain a piece of data. But while variables usually exist in the global space, a property is declared on an object. Properties can, like variables, hold simple types like strings and numbers, but also complex values in the form of other objects.

Naming properties

Now let's talk a bit about how properties can be named. Obviously, you want to use names that will reflect the data that the property should hold. We saw an example of this in the previous article, where we had properties on our user object to hold a name and an age:

let user = 
{
	name: "John Doe",
	age: 42
};

Of course, these are very simple names and you will often find your self using longer and more descriptive names for more complex data. However, for normal usage, there are a couple of rules you might want to adhere to, when naming your properties:

  • Must start with a non-numeric character
  • Must not contain any spaces
  • Must not contain any special characters besides $ and _

These rules are there to make sure that you can actually declare and access the properties without breaking the JavaScript parsing engine.

Square brackets

However, since objects are basically just a collection of key/value pairs, as we already talked about, you can work around this rule quite easily. By specifying the property name as a string instead of an identifier, we can use pretty much any character we want:

let user = 
{
	"full name": "John Doe",
	"a^g^e": 42
};

Of course, this now prevents us from using the dot notation to access the property - JavaScript can't understand if we try to reference "user.full name", because it will not interpret the space as part of the property name. Instead, we need to use square brackets when accessing these properties, like this:

let user = 
{
	"full name": "John Doe",
	"a^g^e": 42
};
alert(user["full name"] + " is " + user["a^g^e"] + " years old");

As you can see from the example, pretty much everything is now possible when it comes to the name of the property.

Computed properties

Square brackets can be used when specifying the name of the property as well. This is referred to as computed properties, because it allows us to let the name of the property be dynamic, e.g. based on input from another source, instead of hardcoded by the programmer.

Here's an example of using computed properties:

let prefix = "user";

let user = 
{
	[prefix + "_name"]: "John Doe",
	[prefix + "_age"]: 42
};
alert(user[prefix + "_name"] + " is " + user[prefix + "_age"] + " years old");

Notice how we use the value of the prefix variable to generate the property names. Since everything between the square brackets are simply evaluated as actual JavaScript code, the possibilities for using computed properties are pretty much endless. Here's another example of what we can do:

let user = {};
for(let i = 1; i <= 5; i++)
{
	user["prop" + i] = "User property #" + i;
}
console.log(user);
/* Example output:
{
  prop1: "User property #1",
  prop2: "User property #2",
  prop3: "User property #3",
  prop4: "User property #4",
  prop5: "User property #5"
}
*/

In this example, we use a loop to generate numbered properties for the object, showing you once more that computed properties are really flexible.

Manipulating properties

So far, we have only seen examples of reading the values of our properties. However, you can of course modify the values they hold after the object has been declared as if it was a normal variable:

let user = 
{
	name: "John Doe",
	age: 42
};
user.age = 43;
// John Doe is 43 years old
alert(user.name + " is " + user.age + " years old");

Adding properties

Objects in JavaScript are very dynamic. This means that you don't necessarily have to declare all the properties when creating the objects - you can add more later on if needed. In fact, its so dynamic that you can simply just assign a value to a non-existing property and JavaScript will just add this property to the object. Here's an example:

let user = {};
user.name = "John Doe";
user.age = 42;
alert(user.name + " is " + user.age + " years old");

Notice how I create an empty object, and then simply assign values to properties called "name" and "age". I can then use them in the exact same way as if the properties had been declared when the object was created.

Deleting properties

If you need to remove a property from an object, we can use the delete operator. It does exactly what the name implies: It deletes the property from the object. Here's an example:

let user = 
{
	name: "John Doe",
	age: 42
};
delete user.name;
// Result: undefined is 42 years old
alert(user.name + " is " + user.age + " years old");

Notice how I delete the name property right before trying to use it, resulting in user.name being "undefined".

Checking if a property exists

You may need to check if a property exists, especially now that we know that they can be deleted after the object has been created. JavaScript comes with the in operator to accomplish just this:

let user = {};
// false
alert("age" in user);

user.age = 42;
// true
alert("age" in user);

As you can see, the syntax is very simple and straightforward, making it easy for us to test for the existence of a property on our object.

Property value shorthand syntax

As mentioned several times by now, objects are just key/value pairs. So up until now, we have specified properties by delivering a key (name) and a value. However, you will often find your self creating objects where you use a variable as the value, using the name of the variable as the key/name for the property.

This sounds a bit complicated, but consider the following example, where we create our user object based on input from a function:

function NewUser(name, age)
{
	let user = 
	{
		name: name,
		age: age
	};
	return user;
}

This is a common way of doing things. Notice how I use the same names for the parameters (name, age) as I use when adding properties to the newly created user object. This gives us the two lines with "name: name" and "age: age".

However, to save us a few keystrokes and perhaps even make the code a bit more readable, JavaScript allows us to omit the name of the property when we base it on another variable (in this case, the parameter). This allows us to rewrite the above example like this:

function NewUser(name, age)
{
	let user = 
	{
		name,
		age
	};
	return user;
}

The properties are now created with the name and value from the parameters, as illustrated by this complete example:

function NewUser(name, age)
{
	let user = 
	{
		name,
		age
	};
	return user;
}
let newUser = NewUser("John Doe", 42)
alert(newUser.name + " is " + newUser.age + " years old");

Not a huge deal, just some nice syntactic sugar.

Summary

Properties are like variables, but for objects - they can be used to store simple types like numbers and strings, or even complex types like other objects. They can even hold a reference to a function, basically allowing you to add methods to an object, as we'll see in the next article.