Mongoose + Node.js,Object.assign(从数据库返回的数据副本)显示附加数据

Sid*_*ury 5 javascript mongoose mongodb node.js

今天我发现了一个有趣的事情,我以前从来不知道。我需要帮助来理解为什么会发生这种情况:

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

这个产量

{
    "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"
    }
}
Run Code Online (Sandbox Code Playgroud)

查看RAWCOPY之间的区别。按照我的理解

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

显然,COPY包含MongoDB的信息,如果RAW已经有了这些数据(隐藏)那么如何才能RAW.email获得,而该数据COPY.emailundefined

在这种情况下,这种抽象是如何工作的RAW

Est*_*ask 5

正如Expressres.json文档所述,

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

JSON.stringify使用可用的toJSON方法来获取对象值。Mongoose 文档支持它

由于toJSON不是 自己的可枚举方法usr,因此在使用 进行浅复制时会被省略Object.assign({}, usr),因此该对象将按原样处理JSON.stringify,并且会公开内部文档属性。

很可能应该是:

 res.json({
      RAW: usr,
      COPY: Object.assign({}, usr.toJSON(), {some: 'change'})
 }) 
Run Code Online (Sandbox Code Playgroud)