猫鼬+ Node.js,Object.assign(从数据库返回的数据的副本)显示了其他数据

时间:2018-06-25 10:40:46

标签: javascript node.js mongodb mongoose

今天,我发现了一件有趣的事情,以前从未知道过。我需要帮助来了解发生这种情况的原因:

User.findOne({email: req.body.email}, function(err, usr){
     return res.json({
          RAW: usr,
          COPY: Object.assign({}, usr, {some: 'change'})
     }) 
})

这个产量

{
    "RAW": {
        "createdAt": "2018-06-25T09:16:35.516Z",
        "_id": "5b30b2f36c492c55a818b455",
        "email": "some@email.com",
        "password": "$2b$08$k5IRBF.1i.q.7D/BD4HCVuOdnIRDQOHaT6icNwIyc1XfeklUwyF5.",
        "__v": 0
    },
    "COPY": {
        "$__": {
            "strictMode": true,
            "selected": {},
            "getters": {},
            "_id": "5b30b2f36c492c55a818b455",
            "wasPopulated": false,
            "activePaths": {
                "paths": {
                    "createdAt": "init",
                    "_id": "init",
                    "email": "init",
                    "password": "init",
                    "__v": "init"
                },
                "states": {
                    "ignore": {},
                    "default": {},
                    "init": {
                        "_id": true,
                        "email": true,
                        "password": true,
                        "createdAt": true,
                        "__v": true
                    },
                    "modify": {},
                    "require": {}
                },
                "stateNames": [
                    "require",
                    "modify",
                    "init",
                    "default",
                    "ignore"
                ]
            },
            "pathsToScopes": {},
            "emitter": {
                "domain": null,
                "_events": {},
                "_eventsCount": 0,
                "_maxListeners": 0
            },
            "$options": true
        },
        "isNew": false,
        "_doc": {
            "createdAt": "2018-06-25T09:16:35.516Z",
            "_id": "5b30b2f36c492c55a818b455",
            "email": "some@email.com",
            "password": "$2b$08$k5IRBF.1i.q.7D/BD4HCVuOdnIRDQOHaT6icNwIyc1XfeklUwyF5.",
            "__v": 0
        },
        "$init": true,
        "some": "change"
    }
}

查看 RAW COPY 之间的区别。根据我的理解

  1. Object.assign()只是使用新的内存地址创建对象的副本。
  2. 然后,RAW.email应该等于COPY.email(但不是,为什么?)

很显然,COPY包含来自MongoDB的信息,如果RAW已经拥有(隐藏)那些数据,那么RAW.email如何获取数据,而COPY.email是{{1 }}。

undefined的情况下,这种抽象如何起作用?

1 个答案:

答案 0 :(得分:3)

Express res.json documentation所述,

  

发送JSON响应。此方法发送响应(具有正确的内容类型),该响应是使用JSON.stringify()转换为JSON字符串的参数。

然后JSON.stringify使用toJSON method来获取对象值。猫鼬文件support it

由于toJSON不是usr自己的可枚举方法,因此在用Object.assign({}, usr)对其进行浅表复制时将其省略,因此JSON.stringify和内部将对象按原样对待文档属性已公开。

可能应该是:

 res.json({
      RAW: usr,
      COPY: Object.assign({}, usr.toJSON(), {some: 'change'})
 })