Reputation: 77
I have UserModel
class which has static methods, and I want to extend or inherit to multiple class instances.
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);
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 }
}
}
But the problem is GettersModel
gets replaced by the prototype of DeleteModel
when setting this:
Object.setPrototypeOf(UserModel, getterModel);
Object.setPrototypeOf(UserModel, deleteModel);
And also, there's a warning in MDN website about .setPrototypeOf()
:
From MDN
Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.
Because this feature is a part of the language, it is still the burden on engine developers to implement that feature performantly (ideally). Until engine developers address this issue, if you are concerned about performance, you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().
So how can I do this? Thanks
Upvotes: 0
Views: 132
Reputation: 664764
You should not use inheritance here. The UserModel
class should use the deleteModel
instance.
To expose UserModel.deleteRow
, you can use
class UserModel {
constructor() {…}
static async insertUser(…) { … }
static deleteRow = deleteModel.deleteRow.bind(deleteModel)
}
or
class UserModel {
constructor() {…}
static async insertUser(…) { … }
}
UserModel.deleteRow = deleteModel.deleteRow.bind(deleteModel);
However, I would suggest that you should not expose a deleteRow
method on your UserModel
- what is a row? You should instead write
class UserModel {
constructor() {…}
static async insertUser(…) { … }
static async deleteUser(userID) {
return {status: await deleteModel.deleteRow(userID)};
}
}
Upvotes: 1