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);