Reflect.setPrototypeOf 和 extends 有区别吗?
发布于 7 年前 作者 ruiming 3097 次浏览 来自 问答

这两种写法有区别吗?

import { Model } from 'sequelize'
class Book extends Model {
  static fields (DataTypes) {
    return {
      title: DataTypes.STRING,
      author: DataTypes.STRING
    }
  }
}
export default Book
import { Model } from 'sequelize'
class Book {
  static fields (DataTypes) {
    return {
      title: DataTypes.STRING,
      author: DataTypes.STRING
    }
  }
}
Reflect.setPrototypeOf(Book, Model)
export default Book

这两个导出来的 Book 类, 使用 init 方法(Model 内提供) 初始化都是可以成功的. 但使用 setPrototypeOf 这种方法, 在调用 findAll 时会查询出一堆空对象如下(findAll 不报错, 但有些方法如 create 会报错):

[ 
  Book {},
  Book {},
  Book {}
]

如果使用 extends 甚至 extends 后再使用 setPrototypeOf 方法, 都可以正确查询出来结果. 求解疑…

2 回复

差别挺大的,最起码的一点,如果你用Object.setPrototypeOf方法获取的Book,下面的函数不成立 const b = new Book() assert(b instanceof Model) Error 你必须要运行下面两个代码才可以 Object.setPrototypeOf(Book, Model) Object.setPrototypeOf(Book.prototype, Model.prototype) 初次之外,extends出来的Book,会调用Model的构造函数,另一种就要手动调用

@sunkuo 恩, 感谢你的回答. 我按你说的去研究了下最终搞定了这个问题了. 目前解决方案是这样的, 这样做后使用 newBook 就一切正常了. 但不知道有没有更好的解决方式或者说这种方式会不会存在问题?

Reflect.setPrototypeOf(Book, Model)
Reflect.setPrototypeOf(Book.prototype, Model.prototype)

const newBook = function () {
  return Reflect.construct(Model, arguments, newBook)
}

Reflect.setPrototypeOf(newBook, Book)
Reflect.setPrototypeOf(newBook.prototype, Book.prototype)
回到顶部