The computed properties feature is common in popular JS frameworks (React, VueJS) but how do we implement this in vanilla JS?
Let's say that given a User class, with a dateOfBirth property, we would like to compute its age, is there a better way to perform this task than the code below?
function User(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.age = function() {
return now() - this.dateOfBirth;
}
}
var driver = new User('Steve', new Date('12 December, 1990'))
driver.age()
In the code above, we are retrieving the age value by calling a method. However, is it possible to be able to retrieve the value with just driver.age?
Whether it's "better" or not is a matter of style/opinion, but if you want a property rather than a method, you can create an accessor property, in your case an accessor with a getter but no setter.
Making minimal changes to your code, you'd do it like this:
function User(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
Object.defineProperty(this, "age", {
get() {
return now() - this.dateOfBirth;
}
});
}
Live Example:
function now() { return Date.now(); }
function User(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
Object.defineProperty(this, "age", {
get() {
return now() - this.dateOfBirth;
}
});
}
var steve = new User("Steve", new Date(1990, 11, 12));
console.log(steve.age);
You can define those more concisely using an object initializer (note that this example throws away the object created via new User and returns a different one instead, which doesn't have User.prototype as its prototype):
function User(name, dateOfBirth) {
return {
name,
dateOfBirth,
get age() {
return now() - this.dateOfBirth;
}
};
}
Live Example:
function now() { return Date.now(); }
function User(name, dateOfBirth) {
return {
name,
dateOfBirth,
get age() {
return now() - this.dateOfBirth;
}
};
}
var steve = new User("Steve", new Date(1990, 11, 12));
console.log(steve.age);
I've also used the new (ES2015+) shorthand property syntax there for name and dateOfBirth.
This is also compatible with ES2015's class syntax:
class User {
constructor(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
}
get age() {
return now() - this.dateOfBirth;
}
}
Live Example:
function now() { return Date.now(); }
class User {
constructor(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
}
get age() {
return now() - this.dateOfBirth;
}
}
var steve = new User("Steve", new Date(1990, 11, 12));
console.log(steve.age);
Yes. You can use a getter to return a computed value, like so:
class User {
constructor(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
}
get age() {
return new Date() - this.dateOfBirth;
}
}
var driver = new User('Steve', new Date('12 December, 1990'));
console.log(driver.age);
More information here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With