5月29日 01:09
Mongoose 实例方法和静态方法有什么区别?
实例方法定义在 schema.methods 上,通过文档实例调用,this 指向当前文档,适合操作单条记录(如密码比对、计算总价)。静态方法定义在 schema.statics 上,通过模型类调用,this 指向模型本身,适合查询和批量操作(如按邮箱查找、统计数量)。核心区别:需不需要访问文档实例数据。
追问
this 上下文在两种方法中分别是什么? 实例方法中 this 是当前 Document 实例,可访问 this.name、this.save() 等。静态方法中 this 是 Model 构造函数,等价于 User,可直接调用 this.find()、this.countDocuments()。
什么时候该用实例方法? 方法逻辑依赖文档自身数据时,比如 comparePassword 需要 this.password、getTotalPrice 需要 this.items。不依赖实例数据的方法放静态方法更合理。
静态方法能替代普通查询吗? 可以,静态方法本质是对查询的封装,让调用方不用关心查询细节。如 User.findByEmail('x') 比 User.findOne({ email: 'x' }) 语义更清晰,也方便统一修改查询逻辑。
两种方法能用箭头函数定义吗? 不能。箭头函数没有自己的 this,会捕获外层作用域的 this,导致无法访问文档实例或模型。必须用 function 关键字定义。
静态方法返回值有什么讲究? 返回 Query 对象可支持链式调用(.sort().limit()),返回 Promise 则终止链式。推荐静态方法返回 this.find() 的 Query,让调用方决定是否加排序或分页。
写段代码
javascript// 实例方法:依赖文档数据 userSchema.methods.comparePwd = function(pwd) { return bcrypt.compare(pwd, this.password); }; // 静态方法:封装查询逻辑 userSchema.statics.findByEmail = function(email) { return this.findOne({ email }); }; // 使用 const user = await User.findByEmail('a@b.com'); await user.comparePwd('123456');