将 class 扩展到多个 class 实例 Javascript
Extend class to a multiple class instances Javascript
我有 UserModel
class 有静态方法,我想扩展或继承到多个 class 实例。
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 }
}
}
但问题是 GettersModel
在设置时被 DeleteModel
的原型替换:
Object.setPrototypeOf(UserModel, getterModel);
Object.setPrototypeOf(UserModel, deleteModel);
此外,MDN 网站上有关于 .setPrototypeOf()
的警告:
来自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().
那我该怎么做呢?谢谢
你不应该在这里使用继承。 UserModel
class 应该 使用 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)};
}
}
我有 UserModel
class 有静态方法,我想扩展或继承到多个 class 实例。
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 }
}
}
但问题是 GettersModel
在设置时被 DeleteModel
的原型替换:
Object.setPrototypeOf(UserModel, getterModel);
Object.setPrototypeOf(UserModel, deleteModel);
此外,MDN 网站上有关于 .setPrototypeOf()
的警告:
来自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().
那我该怎么做呢?谢谢
你不应该在这里使用继承。 UserModel
class 应该 使用 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)};
}
}