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.
Object.getPrototypeOf or proto
Since ES6, __proto__
has become a standard property of an object.
We can get and set it like any other property.
For instance, we can write:
const obj = {};
console.log(obj.__proto__);
to get the prototype of obj
.
We get the object’s prototype with the __proto__
property.
We can set it by writing:
const obj = {};
obj.__proto__ = {
foo: 1
};
console.log(obj.__proto__);
and we get {foo: 1}
as the prototype.
If we want to create an object with a prototype, we can also call Object.create
with a prototype.
So we can write:
const obj = Object.create({
foo: 1
})
and we get the same result.
We cal also use the Object.getPrototypeOf
method to get the prototype of an object.
For instance, we can write:
Object.getPrototypeOf(obj)
and we get the same result as getting the __proto__
property.
The __proto__
property is standard, so we can safely use it to get and set the prototype.
Make Constructors new-Agnostic
If we’re creating a constructor function, then we may be able to call it as a function.
For instance, if we have:
function Person(name) {
this.name = name;
}
const p = Person('james');
console.log(this.name)
Then this
is the global object and the name
property has value 'james'
.
This is definitely not what we want.
If we have strict mode, then this
would be undefined
at the top level, so we can’t create global variables accidentally.
If we have:
function Person(name) {
"use strict";
this.name = name;
}
const p = Person('james');
Then we get the error ‘Uncaught TypeError: Cannot set property ‘name’ of undefined’.
This provides us with some protection from call constructors as a regular function.
To make the check more robust, we can add an instance check into the constructor:
function Person(name) {
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
This way, with or without new
, we still get the Person
instance returned.
The best way is to use the class syntax.
So we can rewrite the constructor to:
class Person {
constructor(name) {
this.name = name;
}
}
This way, if we call Person
without new
, we get the error ‘Uncaught TypeError: Class constructor Person cannot be invoked without ‘new’’.
Conclusion
There’re various ways to get and set the prototype.
Also, the class syntax is the most robust way to create a constructor.