为何Sequelize返回结果与console.log输出结果不一致?
问题:res.json为何只获取Sequelize模型的dataValues属性?
我用Postman发送请求后,返回的数据干净无额外属性,但用console.log打印data时却包含大量框架内部属性。了解到这是因为res.json会将数据序列化为仅包含dataValues中模型属性的普通对象,想知道res.json是如何做到只获取dataValues并忽略其他属性的?
我的代码
async getItems(req, res, next){ const data = await Item.findAll({ attributes: ['id', 'name', 'price'] }); console.log(data); return res.status(200).json(data); };
Postman返回结果
[ { "id": 1, "name": "PS5", "price": 600 }, { "id": 2, "name": "XBOX X", "price": 400 } ]
console.log(data)输出结果
[ Item { dataValues: { id: 1, name: 'PS5', price: 600 }, _previousDataValues: { id: 1, name: 'PS5', price: 600 }, uniqno: 1, _changed: Set(0) {}, _options: { isNewRecord: false, _schema: null, _schemaDelimiter: '', raw: true, attributes: [Array] }, isNewRecord: false }, Item { dataValues: { id: 2, name: 'XBOX X', price: 400 }, _previousDataValues: { id: 2, name: 'XBOX X', price: 400 }, uniqno: 1, _changed: Set(0) {}, _options: { isNewRecord: false, _schema: null, _schemaDelimiter: '', raw: true, attributes: [Array] }, isNewRecord: false } ]
原因解析
核心原因是Sequelize的模型实例自带了toJSON()方法,而Express的res.json()在序列化数据时,会自动调用对象的toJSON()方法。
Sequelize为每个模型实例都内置了这个方法,它的作用就是返回实例的dataValues属性——也就是你定义的业务字段数据,自动过滤掉_previousDataValues、_changed这些框架内部使用的属性。
当你调用res.json(data)时,Express会遍历数组里的每个Item实例,逐个调用它们的toJSON(),把复杂的模型实例转换成只包含业务字段的普通对象,再统一序列化成JSON字符串返回给客户端。
而console.log()是直接打印完整的模型实例对象,它不会触发toJSON()方法,所以会把所有内部属性都显示出来。如果想让console.log也打印干净的数据,可以手动调用toJSON():
console.log(data.map(item => item.toJSON()));
内容的提问来源于stack exchange,提问作者Artix
相关产品推荐
相关产品推荐

