【问题标题】:Extend class to a multiple class instances Javascript将类扩展到多个类实例Javascript
【发布时间】:2021-10-17 19:26:28
【问题描述】:

我有 UserModel 具有静态方法的类,我想扩展或继承到多个类实例。

UserModel.js

const tableName = "Users";
const primaryKey = "UserID";
const secondaryTables = [{ id: "RoleID", name: "Roles", relation: " INNER JOIN " }];
const getterModel = new GettersModel(tableName, primaryKey, secondaryTables);
const deleteModel = new DeleteModel(tableName, primaryKey);

class UserModel {

    constructor() {

    }

    static async insertUser({ username, password, roleId }) {
        ...
    }
    ...
}
Object.setPrototypeOf(UserModel, getterModel);
Object.setPrototypeOf(UserModel, deleteModel);

删除模型.js

class DeleteModel {
    constructor(tableName, primaryKey) {
        this.tableName = tableName;
        this.primaryKey = primaryKey;

    }
     async deleteRow(id) {

        try {
            const result = await mysql_conn.delete(this.tableName, `where 
                                  ${this.primaryKey}=?`, [id]);
            return result;

        } catch (err) {
            console.error(err);
            return false;
        }
    }

}

UserService.js

async function deleteUser(userID) {

        let ret = await UserModel.deleteRow(userID);

        if (ret == false) {
            return { status: false }
        } else {
            return { status: true }
        }

}

但问题是GettersModel 在设置时被DeleteModel 的原型替换:

Object.setPrototypeOf(UserModel, getterModel);
Object.setPrototypeOf(UserModel, deleteModel);

另外,MDN 网站上有一条关于.setPrototypeOf() 的警告:

来自MDN

警告:根据现代 JavaScript 引擎优化属性访问的本质,更改对象的 [[Prototype]] 是 目前在每个浏览器和 JavaScript 引擎中都非常缓慢的操作。此外,更改继承的影响是微妙而广泛的,并且不仅限于在 Object.setPrototypeOf(...) 语句中花费的时间,还可以扩展到可以访问任何对象的任何代码 [ [原型]] 已更改。

因为这个特性是语言的一部分,它仍然是负担 让引擎开发人员高效地实现该功能(理想情况下)。 在引擎开发人员解决这个问题之前,如果您担心 性能,您应该避免设置对象的 [[Prototype]]。 相反,使用所需的 [[Prototype]] 创建一个新对象 Object.create()。

那么我该怎么做呢?谢谢

【问题讨论】:

    标签: javascript jquery node.js ecmascript-6 prototype


    【解决方案1】:

    你不应该在这里使用继承。 UserModel 类应该使用 deleteModel 实例。

    要公开UserModel.deleteRow,可以使用

    class UserModel {
        constructor() {…}
        static async insertUser(…) { … }
        
        static deleteRow = deleteModel.deleteRow.bind(deleteModel)
    }
    

    class UserModel {
        constructor() {…}
        static async insertUser(…) { … }
    }
    UserModel.deleteRow = deleteModel.deleteRow.bind(deleteModel);
    

    但是,我建议您不要在 UserModel 上公开 deleteRow 方法 - 什么是行?你应该写

    class UserModel {
        constructor() {…}
        static async insertUser(…) { … }
        
        static async deleteUser(userID) {
            return {status: await deleteModel.deleteRow(userID)};
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-14
      • 2017-05-08
      • 1970-01-01
      • 2013-05-24
      • 2013-07-04
      • 1970-01-01
      • 2021-02-19
      • 1970-01-01
      相关资源
      最近更新 更多