Objects

As we know from the chapter Data types, there are seven language types in JavaScript. Six of them are called “primitive”, because their values contain only a single thing (be it a string or a number or whatever).

In contrast, objects are used to store keyed collections of various data and more complex entities. In JavaScript, objects penetrate almost every aspect of the language. So we must understand them first before going in-depth anywhere else.

An object can be created with figure brackets {…} with an optional list of properties. A property is a “key: value” pair, where key is a string (also called a “property name”), and value can be anything.

We can imagine an object as a cabinet with signed files. Every piece of data is stored in it’s file by the key. It’s easy to find a file by it’s name or add/remove a file.

An empty object (“empty cabinet”) can be created using one of two syntaxes:

Here, the variable key may be calculated at run-time or depend on the user input. And then we use it to access the property. That gives us a great deal of flexibility. The dot notation cannot be used in a similar way.

That can become a source of bugs and even vulnerabilies if we intent to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys.

In that case the visitor may choose “proto” as the key, and the assignment logic will be ruined (as shown above).

There exist a way to make objects treat __proto__ as a regular property, we’ll cover it later, but first we need to know more about objects to understand it.
There’s another data structure Map, that we’ll learn in the chapter Map, Set, WeakMap and WeakSet, which supports arbitrary keys. Also

A notable objects feature is that it’s possible to access any property. There will be no error if the property doesn’t exist! Accessing a non-existing property just returns undefined. It provides a very common way to test whether the property exists – to get it and compare vs undefined:

The example above demonstrates that there is only one object. Like if we had a cabinet with two keys and used one of them (admin) to get into it. Then, if we later use the other key (user) we would see changes.

For comparisons like obj1 > obj2 or for a comparison against a primitive obj == 5, objects are converted to primitives. We’ll study how object conversions work very soon, but to say the truth, such comparisons are necessary very rarely and usually are a result of a coding mistake.

It might seem that the line (*) would cause an error, but no, there’s totally no problem. That’s because const fixes the value of user itself. And here user stores the reference to the same object all the time. The line (*) goes inside the object, it doesn’t reassign user.

The const would give an error if we try to set user to something else, for instance:

To fix that, we should use the cloning loop that examines each value of user[key] and, if it’s an object, then replicate it’s structure as well. That is called a “deep cloning”.

There’s a standard algorithm for deep cloning that handles the case above and more complex cases, called the Structured cloning algorithm. In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library lodash, the method is called _.cloneDeep(obj).

Square brackets notation obj["property"]. Square brackets allow to take the key from a variable, like obj[varWithKey].

Additional operators:

To delete a property: delete obj.prop.

To check if a property with the given key exists: "key" in obj.

To iterate over an object: for(let key in obj) loop.

Objects are assigned and copied by reference. In other words, a variable stores not the “object value”, but a “reference” (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object. All operations via copied references (like adding/removing properties) are performed on the same single object.

What we’ve studied in this chapter is called a “plain object”, or just Object.

There are many other kinds of objects in JavaScript:

Array to store ordered data collections,

Date to store the information about the date and time,

Error to store the information about an error.

…And so on.

They have their special features that we’ll study later. Sometimes people say something like “Array type” or “Date type”, but formally they are not types of their own, but belong to a single “object” data type. And they extend it in various ways.

Objects in JavaScript are very powerful. Here we’ve just scratched the surface of the topic that is really huge. We’ll be closely working with objects and learning more about them in further parts of the tutorial.