【问题标题】:'Computed Property' in Vanilla Javascript ClassVanilla Javascript 类中的“计算属性”
【发布时间】:2019-05-15 08:25:02
【问题描述】:

计算属性 特性在流行的 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 检索值?

【问题讨论】:

标签: javascript


【解决方案1】:

它是否“更好”是风格/意见的问题,但如果你想要一个属性而不是方法,你可以创建一个访问器属性,在你的情况下一个访问器具有getter 但没有 setter

对您的代码进行最少的更改,您可以这样做:

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.log(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.log(steve.age);

我还为namedateOfBirth 使用了新的(ES2015+)速记属性语法

这也兼容 ES2015 的 class 语法:

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.log(steve.age);

【讨论】:

  • 不创建user.prototype的第二个代码示例有明显的优势吗?
  • @puoygae - 它是创建的,只是没有被使用。这也是风格问题。就个人而言,我不喜欢使用new X,除非我正在使用X.prototype(直接或通过class 语法)。因此,如果我选择第二个选项,我可能会称它为createUser,而在没有new 的情况下调用它。但我喜欢原型,我喜欢new,所以这些天我倾向于class 语法。
【解决方案2】:

是的。您可以使用 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.log(driver.age);

更多信息here

【讨论】:

  • 感谢您的回答。虽然这个答案是正确的,甚至使用了最新的 ES6 类,但我还是选择了 T.J. Crowder 的回答,因为它对应于我在问题中使用的 JS 版本。
猜你喜欢
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多