Javascript类与Node.js中函数的“列表”

时间:2019-08-31 06:57:24

标签: javascript node.js function class

我是一种编程新手,我现在想知道自己与NodeJs中相关函数的简单列表相比,类的好处是什么。

作为一个非常简单的示例,我想如果要使用Class,我会创建一个这样的用户:

class User {
    constructor(email) {
        this.email = email;
    }

    validateEmail() {
        // whatever function that checks if this.email is valid
        if (this.email === 'notValid') {
            throw new Error();
        }
        return this;
    }

    create() {
        this.validateEmail();
        // whatever function that inserts user in the database
        return user;
    }
}

const newUser = new User('test@test.com');
const user = newUser.create();

我会用相关功能的“列表”做类似的事情:

const validateEmail = email => {
    // whatever function that checks if valid email
    if (email === 'notValid') {
        throw new Error();
    }
    return true;
};

const createUser = email => {
    if (validateEmail(email)) {
        // whatever function that inserts the user in the database
        return user;
    }
};

const user = createUser('test@test.com');

在我看来,第二种方法可以减少一些代码。而且甚至不必实例化课程。

假设我有一个节点API,其中包含多个“用户”路由和控制器。我想我每次调用用户路由/控制器时都必须实例化用户类,对吗?作为一个初学者,这对我来说听起来并不是“优化”的……但是我肯定会缺少一些东西……

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

类将数据(实例this上的属性)与功能(每个实例的内部原型上的功能)联系起来。

如果您从未拥有与实例相关联的有意义的数据,那么拥有一个类就没有多大意义了。在这里,您确实拥有数据(电子邮件字符串)一个相关函数(validateEmail),所以类是一个可能的选择,尽管在有更多的属性和更多的功能。 (如果只有一个属性,并且该属性仅存在,因此可以使用一个函数调用它,则类的确确实显得不必要冗长。)

此类的一个好处是,一旦有了实例,就可以将该实例传递给任何其他模块(或作用域),并且该模块可以调用与该实例 related 相关的函数,而不必导入等效的独立功能。例如,假设您的User类的使用者是否在另一个模块中,而使用者希望能够创建用户进行验证。然后,导出大量用户代码的模块要么必须

(1)导出许多独立功能(可能会有些乏味且难以管理),或者

(2)仅导出 一个类

能够仅导出一个类并让该类或其实例的任何用户使用与类相关的方法非常方便-这样,您不必每次使用一个User时都传递多个值相关功能。

想象一下,模块A是否需要能够创建用户,模块B是否需要能够验证用户,模块C是否需要能够查看用户是否已经通过验证。如果主用户文件为上述每一项创建并导出了独立的函数,并且每个使用模块都导入了他们需要调用的内容,那么事情将变得有些丑陋。但是,如果主用户文件创建并导出了一个类,那将是微不足道的:用户(模块A)的创建者将导入该类,实例化对象const user = new User('a@a.com'),并将其传递给模块B,这可以然后调用user.validateEmail()(无需导入)。然后,最终用户实例传递给模块C,该模块调用user.checkIfUserIsValidated()(同样,不需要导入)。

使用Class方法,在同一个对象(类实例)上拥有一个同时具有实例数据相关功能的对象,可以使代码更加简洁。

当然,如果您不想使用 ,就永远不会使用它,但这是一个可能的好处。

答案 1 :(得分:0)

在给出的示例中,您确实有一个要点:

  • 用于验证电子邮件的函数实际上并不需要实例化的对象,实际上,您想要在 创建API的对象实例之前运行它。

  • 一个真正返回 different 对象(user不是User的实例)而不改变this对象的函数,并不是单独上课的最佳理由。与已经可以访问的API对象类(返回user)相比,如果仅此(电子邮件验证)就需要做“额外”操作,那么第二种方法就可以了。

但是,如果您要使用其他一些功能来扩展该API,例如:

  • 准备个性化电子邮件,您需要为其提供姓名,地址,电子邮件,性别...
  • 根据几个属性(年龄,上次登录日期,访问级别等)返回一些计算出的分数
  • ...

...那么使用第一种模式可能会更好-尽管还是有意见的。

我建议仍然创建自己的类,但让它立即创建API的对象,并使返回的对象值成为您自己的实例的属性。然后,这个新对象就是API接口的组成,带有您自己的扩展。

也许是这样:

function validateEmail(email) {
    // whatever function that checks if an email is valid
    if (email === 'notValid') {
        throw new Error();
    }
}

class User  {
    constructor(email) {
        this.rank = 10; // Let's say you need this property that is not offered by the API
        validateEmail(email);
        // whatever function that inserts user in the database
        this.apiUser = api.createUser(email);
    }

    promote() { // Some function using the new properties
        if (this.rank > 1) this.rank--;
    }

    prepareEmail() { // Other function using a mix
        return {
            sentBy: "admin@mysite.com",
            to: this.apiUser.get("email"),
            body: `Dear ${this.apiUser.get("name")}, your current rank is ${this.rank}`
        };
    }
}

const user = new User('test@test.com');

因此,在这里您看到主代码创建了一个对象实例。 API的对象实例封装在其中。您可以使用user.apiUser.someApiMember语法允许调用者直接使用API​​,也可以在自己的类中创建自己的包装函数,以user.myApiWrapperMember的形式访问。