javascript - 不使用Object.setPrototypeOf设置构造函数的原型(prototype)?

标签 javascript

我一直在研究一种类似 ORM 的方法来在 Node.JS 应用程序中处理我的模型,并且我对其工作方式感到满意;但是,我想知道是否有更好的方法来处理重置构造函数的原型(prototype)。

我想要的行为是这样的:

function Person(data) {
  for (const key in data) {
    this[key] = data[key]
  }
}

// setting methods and so on here

Person.findAll() // returns a list of all persons from the db
Person.findOne(id) // returns a person at that ID

const self = new Person(data) // creating a person object
self.save() // saves that object in the db
self.update(data) // updates person object
self.addFriend(id) // creates a record adding the given id as a friend

构造函数 Person 上有一些方法可以访问所有 Person 记录,而 Person 的每个实例都有只影响该记录的方法一项记录。我是这样管理的:

const utils = (tablename) => ({
  findAll: () => dbHandler(`SELECT * FROM ${tablename}`),
  findOne: id => dbHandler(`SELECT * FROM ${tablename} WHERE id = $1`, [id]),
  // etc
})

Object.setPrototypeOf(Person, utils('people'));

.setPrototypeOf 不是最好的方法;它的性能不是特别好。我想知道是否有更好的方法来处理这样的用例——例如,es6 类规范中是否有任何内容可以处理这个问题? (扩展类并不是我想要的;Person.findAll()self.update(data) 之间的区别对我来说很重要,而且我希望 util 方法位于构造函数本身。)

编辑:向下面的 Bergi 提出解决方案(“只需使用 Object.assign”)...这里有一个小演示:

const dbHandler = (string, arr) => console.log(string, arr)

function Person(data) {
  for (const key in data) {
    this[key] = data[key]
  }
}

const utils = (tablename) => ({
  findAll: () => dbHandler(`SELECT * FROM ${tablename}`),
  findOne: id => dbHandler(`SELECT * FROM ${tablename} WHERE id = $1`, [id]),
  // etc
})

Object.assign(Person, utils('people'));

Person.prototype.save = function() {
  console.log(`Saving person with data ${JSON.stringify(this)} to a totally real database`)
}

Person.findAll()
Person.findOne(1)

const self = new Person({
  name: 'j',
  class: 'wizard'
})
self.save()

最佳答案

这里没有理由涉及任何继承(并且设置构造函数的原型(prototype)以使其不再从 Function.prototype 继承确实很奇怪)。只需将静态方法分配为 Person 构造函数对象的属性即可:

Object.assign(Person, utils('people'));

这与

具有相同的效果
function createUtils(obj, tablename) {
  obj.findAll = () => dbHandler(`SELECT * FROM ${tablename}`);
  obj.findOne = id => dbHandler(`SELECT * FROM ${tablename} WHERE id = $1`, [id]);
  // etc
}
createUtils(Person, 'people');

关于javascript - 不使用Object.setPrototypeOf设置构造函数的原型(prototype)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57364132/

相关文章:

javascript - 检查文本字段是否包含javascript中的字母

javascript - 使用 javascript createElement 创建一个 <br/>?

javascript - AppSync HTTP 解析程序 IAM 授权错误

javascript - Angular JS 无法捕获 div 元素

javascript - AngularJS 提示没有为 jquery 定义初始化

javascript - 流媒体视频如何工作?

javascript - 访问 RequireJS 路径配置

javascript - iPhone 5 和全 Canvas 宽度

javascript - YouTrack 工作流程 : Prevent Deletion

javascript - 如何使用 Firebase 云消息传递在 Angular/Ionic 中推送客户端到客户端通知?