Mongoose documentation for toObject列出了toObject
的功能,选项和功能示例。
toJSON
的Mongoose文档说选项与toObject相同,但没有解释toJSON
的作用。 Elsewhere the documentation says
toJSON与toObject选项完全相同,但仅适用 当调用文档的toJSON方法时。
toJSON
的别名是toObject
吗?如果没有,有什么区别?
答案 0 :(得分:18)
查看source code会发现两种方法都调用了内部$toObject
方法,但toJSON
传递了第二个true
参数:
Document.prototype.toObject = function (options) {
return this.$toObject(options);
};
...
Document.prototype.toJSON = function (options) {
return this.$toObject(options, true);
};
第二个参数确定$toObject
是否使用toJSON
或toObject
架构选项作为其默认值。因此,除非这些模式选项的配置不同,否则这两种方法是相同的。
答案 1 :(得分:4)
与JohnnyHK's anwser一样,toJSON
和toObject
之间没有区别。我的猜测是,toJSON
是为了支持JSON.stringify
方法而创建的。
从MDN document开始,如果一个对象具有toJSON
属性作为函数,JSON.stringify
将使用toJSON
函数来序列化对象而不是对象本身。
答案 2 :(得分:2)
在为toObject
和toJSON
方法开发插件时,我发现在保存操作期间也会调用toObject
。这可能是有害的。例如,如果设置toObject
(与我的)一样的插件会改变字段,则该更改的结果将保持不变。
答案 3 :(得分:0)
对于我的用例,这就是我得到的:
.toJSON
的优点是JSON.stringify
自动使用它。如果将架构选项toJSON
设置为重塑选项,则当使用该架构对文档进行字符串化处理时,将构建具有适当形状的对象
.toObject
的优点是,JSON.stringify
有时会在断开文档和架构之间的链接之后运行,因此不会发生任何重塑。在这种情况下,您只需使用这些选项调用文档方法toObject
,即可获得具有适当形状的对象。
示例
const reshapingOptions = {
// include .id (it's a virtual)
virtuals: true,
// exclude .__v
versionKey: false,
// exclude ._id
transform: function (doc, ret) {
delete ret._id;
return ret;
},
};
const friendSchema = mongoose.Schema({
givenName: String,
familyName: String,
}, { toJSON: reshapingOptions });
const friendModel = mongoose.model('Friend', friendSchema);
const john = friendModel.findOne({ givenName: 'John' });
if (!john) {
res.status(404).json({ error: 'No John Found' });
}
语句
JSON.stringify(john);
返回:
{
"id": "...",
"givenName": "John",
"familyName": "Doe"
}
但这是无辜的声明
JSON.stringify({
...john, // the spread breaks the link
role: 'dummy friend'
})
突然返回:
{
"_id": "...",
"givenName": "John",
"familyName": "Doe",
"__v": 0,
"role": "dummy friend"
}
这样我就用
res.json({
...john.toObject(reshapingOptions),
role: 'dummy friend'
})
获得:
{
"id": "...",
"givenName": "John",
"familyName": "Doe",
"role": "dummy friend"
}