JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.
In this article, we’ll look at the best way to work with objects in our JavaScript code.
Use Property Value Shorthand
The property value shorthand is a great way to shorten our way that we define our objects.
With it, if the key and value have the same identifier, then we can shorten ut by combining it into one.
For instance, instead of writing the following code:
const x = 1,
y = 2;
const obj = {
x: x,
y: y
};
We can instead write:
const x = 1,
y = 2;
const obj = {
x,
y
};
As we can see, it’s much shorter and easier to read when there’s only one identifier rather than repeating identifiers.
They both set x
to 1 and y
to 2 within the obj
object.
Group Shorthand Properties At the Beginning of the Object
Shorthand properties should be grouped at the beginning of the object so that we can tell that those properties are defined with the shorthand.
For instance, we can write something like the following to define our object:
const x = 1,
y = 2;
const obj = {
x,
y,
foo: 1,
bar: 2
};
Then we know that x
and y
are populated with the shorthand and foo
and bar
are defined from scratch within the object.
Only Quote Properties That are Invalid Identifiers
We should only quote properties that are invalid identifiers within our object.
This is because valid identifiers don’t need to be quoted so they’re redundant there.
For instance, if we have the following:
const obj = {
'x': 1
};
Then we don’t need the quote around the x
since x
is a valid identifier.
A valid identifier is alphanumeric and can’t start with a digit. It can also have an underscore or dollar sign.
In the other hand, if we have the following code:
const obj = {
'x-1': 1
};
Then we need quotes around x-1
since x-1
isn’t a valid identifier.
Don’t Call Object.prototype
Methods Directly
Object.prototype
methods like hasOwnProperty
, propertyIsEnumerable
, and isPrototypeOf
shouldn’t be called on the object itself since it may be shadowed by the properties on the object in question.
Our object may have noninherited properties with the same name, or it might have been created without the Object
prototype by calling Object.create(null)
.
Therefore, to make sure that we can call those methods, we should write something like the following:
const obj = {
a: 1
};
const hasA = Object.prototype.hasOwnProperty.call(obj, 'a');
In the code above, we called the hasOwnPrototype
object instance method by using the call
method on Object.prototype.hasOwnProperty
.
The first argument is our obj
object which is the value of this
that we use in the hasOwnProperty
method.
The 2nd argument is the argument that we pass into hasOwnProperty
.
We can also cache the method with a constant so that we don’t have to do the lookup for the method every time that we call it.
To do that, we can write the following code:
const obj = {
a: 1
};
const hasProperty = Object.prototype.hasOwnProperty;
const hasA = hasProperty.call(obj, 'a');
In the code above, we cached Object.prototype.hasOwnProperty
by assigning it to the hasProperty
constant so that we can just use that to call the method.
Photo by Bimata Prathama on Unsplash
Prefer the Object Spread Operator Over Object.assign
to Shallow Copy Objects
The spread operator lets us do a shallow copy and merge objects in a way that’s shorter than calling Object.assign
.
For instance, instead of writing the following:
const obj = {
a: 1
};
const obj1 = {
b: 1
};
const merged = Object.assign({}, obj, obj1);
In the code above, we merged the obj
and obj1
objects into an empty object by calling Object.assign
. The first argument has the object that we want to merge into.
Therefore, the merged
constant would have the value {a: 1, b: 1}
.
To do a shallow copy, we write the following code:
const obj = {
a: 1
};
const copy = Object.assign({}, obj);
In the code above, we make a shallow copy of obj
, which just copies the top-level properties and leave other properties referencing the original object, by putting all the properties if obj
into an empty object.
Object.assign
is once again is called with the empty object as the first argument, which is the object that we’ll put the copied properties into.
Therefore, copy
will have the same properties as obj
.
With the spread operator, we can do this in a much shorter way. To merge objects, we write:
const obj = {
a: 1
};
const obj1 = {
b: 1
};
const merged = {
...obj,
...obj1
};
The spread operator ...
spreads the properties into the object that it’s in.
To do a shallow copy, we write the following:
const obj = {
a: 1
};
const copy = {
...obj
};
It’s the same thing except that we only have one object.
Conclusion
We should use the spread operator to make shallow copies of objects and merge multiple objects into one.
If we have shorthands like the property shorthand, then we should use it.
Finally, don’t call Object.prototype
methods directly since they may not exist for various reasons.