Like any kind of apps, JavaScript apps also have to be written well.
Otherwise, we run into all kinds of issues later on.
In this article, we’ll look at ways to improve our JavaScript code.
Build Dictionaries From Objects
Dictionaries are data structures with key-value pairs.
JavaScript objects can have key-value pairs added and removed dynamically.
So we can add items and remove them.
For instance, we can write:
const dict = {
james: 33,
bob: 22,
mary: 41
};
Then we can loop through the entries in various ways.
We can use the for-in loop to loop through the items:
for (const name in dict) {
console.log(name, dict[name]);
}
We can get the keys with Object.keys
by writing:
for (const name of Object.keys(dict)) {
console.log(name, dict[name]);
}
We switched in
with of
.
Also, we can get all the entries with Object.entries()
:
for (const [name, age] of Object.entries(dict)) {
console.log(name, age);
}
We destructured the key-value pairs in the loop heading.
Every object inherits from the Object.prototype
, so we get methods like toString
and other properties from it.
Object.keys
, Object.entries
only loop through own properties so this won’t be a problem.
The delete
operator lets us delete properties from an object.
So we can write:
delete james
to remove the james
property.
We shouldn’t use arrays to represent dictionaries.
Arrays can have properties since they’re also objects.
But that’s the wrong way to use arrays.
For instance, if we have:
const dict = new Array();
dict.james = 34;
dict.bob = 24;
dict.mary = 62;
then we shouldn’t use it as an object.
Some languages like PHP have associative arrays which are dictionaries.
Use null Prototypes to Provent Prototype Pollution
The prototype of an object is Object.prototype
by default.
So if we have:
Object.getPrototypeOf({})
We get the Object.prototype
returned.
To create an object with an null
prototype, we can pass in an Object.create
method with the null
prototype.
For instance, we can write:
const obj = Object.create(null);
Then Object.getPrototypeOf(obj)
is null
.
We can also set the __proto__
property of an object by writing:
const obj = { __proto__: null };
This is a standard property since ES6 for setting the prototype so we can use it to set the prototype to null
.
Use hasOwnPropety to Protect Against Prototype Pollution
The in
operator can check if an object has a given property.
It also checks the prototype for such properties.
For instance, if we have:
const dict = {
james: 33,
bob: 22,
mary: 41
};
Then if we have:
console.log('james' in dict);
console.log('toString' in dict);
both log true
.
toString
is inherited from Object.prototype
.
We can use the hasOwnProperty
to check only for non-inherited properties.
For instance, we can write:
dict.hasOwnProperty("james");
then that returns true
.
But if we have:
dict.hasOwnProperty("toString");
that returns false
.
Conclusion
The in
operator checks if a property is in the object and its prototype.
hasOwnProperty
only checks for non-inherited properties.
Objects are handy for creating dictionaries.