Функция вычисляемые свойства распространена в популярных JS-фреймворках (React, VueJS), но как мы реализуем ее в vanilla JS?
Предположим, что для данного класса User со свойством dateOfBirth мы хотели бы вычислить его age, есть ли лучший способ выполнить эту задачу, чем приведенный ниже код?
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()
В приведенном выше коде мы получаем значение age, вызывая метод. Однако возможно ли получить значение только с помощью driver.age?
да, вы можете использовать getter
Хотя код, который вы представили, очень неполный
связанные: stackoverflow.com/questions/4822953/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Является ли это «лучше» или нет, это вопрос стиля/мнения, но если вам нужно свойство, а не метод, вы можете создать свойство доступа, в вашем случае аксессор с добытчик, но без сеттер.
Внося минимальные изменения в свой код, вы бы сделали это так:
function User(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
Object.defineProperty(this, "age", {
get() {
return now() - this.dateOfBirth;
}
});
}
Живой пример:
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.info(steve.age);Вы можете определить их более кратко, используя инициализатор объекта (обратите внимание, что в этом примере отбрасывается объект, созданный с помощью new User, и вместо этого возвращается другой, у которого нет User.prototype в качестве прототипа):
function User(name, dateOfBirth) {
return {
name,
dateOfBirth,
get age() {
return now() - this.dateOfBirth;
}
};
}
Живой пример:
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.info(steve.age);Я также использовал новый (ES2015+) сокращенный синтаксис свойства для name и dateOfBirth.
Это также совместимо с синтаксисом class ES2015:
class User {
constructor(name, dateOfBirth) {
this.name = name;
this.dateOfBirth = dateOfBirth;
}
get age() {
return now() - this.dateOfBirth;
}
}
Живой пример:
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.info(steve.age);Есть ли очевидное преимущество во втором примере кода, где user.prototype не создается?
@puoygae - это созданный, просто он не используется. Это также вопрос стиля. Лично мне не нравится использовать new X, если только я не использую X.prototype (напрямую или через синтаксис class). Так что, если бы я выбрал второй вариант, я бы, вероятно, назвал его createUser и назвал бы его без new. Но мне нравятся прототипы и мне нравится new, поэтому сейчас я склоняюсь к синтаксису class.
да. Вы можете использовать getter для возврата вычисленного значения, например:
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.info(driver.age);Дополнительная информация здесь.
Спасибо за этот ответ. Хотя этот ответ правильный и даже использует последний класс ES6, я решил выбрать T.J. Ответ Краудера, потому что он соответствует версии JS, которую я использовал в своем вопросе.
Здесь нет вычисляемых имен свойств. Лучше поставить
ageна прототипе