在使用 MongoDB 进行开发时很常用的工具就是 Mongoose。在 Mongoose 中,虚拟属性和虚拟方法是两个非常有用的功能,可以帮助我们更方便地操作数据,本篇文章将详细介绍 Mongoose 中的虚拟属性和虚拟方法使用方法和实例。
虚拟属性
虚拟属性是指能够在 Mongoose 模型中定义的,但是并没有在 MongoDB 数据库中保存的属性。它们可以像其他属性一样使用,但是在保存到数据库中时会忽略掉。虚拟属性通常用于对现有属性进行衍生或转换。
定义虚拟属性
在 Mongoose 模型中定义虚拟属性很简单:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ---------- - --- ----------------- ---------- ------- --------- ------- --- ------------------------------------------- -- - ------ -------------- - - - - -------------- ---
上面的代码中,我们定义了一个名为 fullName
的虚拟属性,这个属性的值是通过 firstName
和 lastName
属性拼接而来的。其中,fullName
属性是通过调用 virtual
方法来定义的,这个方法传入的第一个参数为虚拟属性的名称,第二个参数为一个 get
方法,在这个方法内部我们可以自定义计算虚拟属性的值的逻辑。
使用虚拟属性
当我们获取一个 Mongoose 模型实例时,我们可以像获取普通属性一样获取虚拟属性:
const User = mongoose.model('User', UserSchema); const user = new User({ firstName: 'John', lastName: 'Doe', }); console.log(user.fullName); // 'John Doe'
注意:虚拟属性只会在获取值时计算一次,如果后续对相关属性进行了修改,虚拟属性的值不会自己更新。要想更新虚拟属性的值,需要手动调用
user.invalidate('fullName')
方法来通知 Mongoose 重新计算虚拟属性的值。
虚拟方法
虚拟方法是指能够在 Mongoose 模型中定义的方法,与虚拟属性不同的是,虚拟方法是一个函数。我们可以定义任何我们需要的方法,这些方法可以访问模型的其他属性和方法。
定义虚拟方法
在 Mongoose 模型中定义虚拟方法也很简单:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ---------- - --- ----------------- ---------- ------- --------- ------- --- ---------------------------------------------- -- - ------ -------- -- - ------ -------------- - - - - -------------- -- ---
上面的代码中,我们定义了一个名为 getFullName
的虚拟方法,这个方法的返回值是一个函数,这个函数在被调用时返回 firstName
和 lastName
组成的字符串。
使用虚拟方法
当我们获取一个 Mongoose 模型实例时,我们可以像获取普通方法一样获取虚拟方法:
const User = mongoose.model('User', UserSchema); const user = new User({ firstName: 'John', lastName: 'Doe', }); console.log(user.getFullName()); // 'John Doe'
深入学习虚拟属性和虚拟方法
Mongoose 的虚拟属性和虚拟方法可以大大简化我们的业务逻辑代码,并且增强了 Mongoose 模型的灵活性。因此,深入掌握虚拟属性和虚拟方法的使用方法和实现原理对于 Mongoose 开发者来说非常重要。
使用示例
在一个 Blog 应用中,我们有一篇名为 My First Blog
的文章,存储在一个名为 Article
的 Mongoose 模型中:
-- -------------------- ---- ------- ----- ------------- - --- ----------------- ------ - ----- ------- --------- ----- -- -------- - ----- ------- --------- ----- -- ---------- - ----- ----- -------- --------- -- --- ----- ------- - ------------------------- ---------------
现在我们希望可以通过 createdAt
属性获取文章的发布时间信息,但是 createdAt
是一个日期类型的属性,不太方便展示出来。因此,我们可以使用虚拟属性来获取格式化过的发布时间,并在默认文档转化为 JSON 格式时自动地展示出来:
-- -------------------- ---- ------- ------------------------------------------------- -- - ------ --------------------------- --- --------------------------- - ---------- ----- ---- -- - --------------- - ---------------- ------ -------------- ------ -------- ------ -------- ------ ---- -- ---
此时,我们可以在获取 Article 实例时,直接通过 publishedAt
属性获取格式化过的发布时间信息:
const article = await Article.findOne({ title: 'My First Blog' }); console.log(article.publishedAt); // '2022-01-01' console.log(JSON.stringify(article)); // '{"title": "My First Blog", "content": "<p>Hello World</p>", "publishedAt": "2022-01-01T00:00:00.000Z"}'
实现原理
在 Mongoose 内部,虚拟属性和虚拟方法的实现是依赖于 JavaScript 中的 defineProperty
方法的,通过该方法,我们可以为一个对象定义虚拟属性和虚拟方法,并将真实的属性和方法绑定到对象上。在 Mongoose 中,虚拟属性和虚拟方法的调用都是通过 get
和 set
方法来实现的。
对于虚拟属性,当我们尝试获取该属性的值时,Mongoose 会调用其 get
方法来计算虚拟属性的值并返回。
对于虚拟方法,当我们尝试调用该方法时,Mongoose 会调用其 get
方法获取方法本身,并返回一个函数,通过这个函数,我们就可以操作模型实例的其他属性和方法。
总结
通过本文,我们学习了 Mongoose 中的虚拟属性和虚拟方法,它们可以大大简化我们的代码逻辑并增强 Mongoose 模型的灵活性。在实际开发中,我们可以通过虚拟属性和虚拟方法来对实际数据进行衍生和转换,以便更方便地操作数据。同时,我们也深入学习了虚拟属性和虚拟方法的使用方法和实现原理,在这个基础上,我们可以更好地应用这些概念来实现我们的业务需求。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648948b048841e9894793b88