【问题标题】:underscore.js .keys and .omit not working as expectedunderscore.js .keys 和 .omit 没有按预期工作
【发布时间】:2014-11-04 05:10:11
【问题描述】:

我正在运行一个可以通过 Mongoose 访问的 MongoDB 来存储用户记录。我在服务器上也有下划线。我有一个带有从数据库返回集合(对象数组)的路由的 RESTful API。我想将完整集合返回给客户端从每个对象中删除密码元素,这样就不会发送给客户端。在任何人说什么之前,我将在最终版本中使用 bcrypt 对密码进行加盐和哈希处理:)

今天我在数据库中只有一个条目,用于用户“管理员”。这是我路线中的代码:

app.get('/users', function(req, res) {
  User.find().sort({'userName': 'ascending'}).exec(function(err, data) {
    _.each(data, function (element, index, list) {
      console.log('userName=' + element.userName);
      console.log('password=' + element.password);
      delete element.password;
      console.log('keys: ' + _.keys(element));
      console.log('password=' + element.password);
      console.log(_.omit(element, 'password'));
    });
    res.json(data);
  });
});

我返回给浏览器的是:

[{"_id":"54058e6eb53dd60730295f59","modifiedOn":"2014-09-01T15:19:10.012Z",
"userName":"administrator","password":"stackoverflow","role":"administrator",
"__v":0,"createdBy":"54058e6eb53dd60730295f59","createdOn":"2014-09-01T15:19:10.004Z",
"previousLogins":[],"accountIsLocked":false,"loginAttempts":0}]

这很好,因为 res.json(data) 语句只是将原始 data 发送回浏览器 - 这不是问题。问题是delete(如果我使用.omit)似乎不适用于我的收藏!如您所见,有很多 console.log 用于调试,输出如下:

userName=administrator
password=stackoverflow
keys: $__,isNew,errors,_maxListeners,_doc,_pres,_posts,save,_events
password=stackoverflow
{ _id: 54058e6eb53dd60730295f59,
  modifiedOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST),
  userName: 'administrator',
  password: 'stackoverflow',
  role: 'administrator',
  __v: 0,
  createdBy: 54058e6eb53dd60730295f59,
  createdOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST),
  previousLogins: [],
  accountIsLocked: false,
  loginAttempts: 0 }

_.keys 的输出显示了我在 console.log(element) 时看不到的键(我假设来自对象原型?),但没有可通过 element.key 访问的键。

知道为什么我会看到这种行为吗?

【问题讨论】:

  • 这真的很奇怪。看,_.keys 不应该访问对象原型的属性。 console.log(element.__proto__.constructor) 显示什么?
  • 是的,我也觉得很奇怪! onsole.log(element.__proto__.constructor) 输出大量条目...这是一个 pastebin 链接:link

标签: javascript object mongoose underscore.js


【解决方案1】:

问题在于,传入exec回调函数的data实际上是一个Document对象——可以认为是Mongoose创建的Models的集合。这些对象有很多有用的方法,它们会记住与 db 等的连接 - 但您将无法将它们作为普通对象处理。

解决方案是通过lean() 向 Mongoose 指示您实际上想要纯 JS 对象作为查询的结果:

User.find().sort({'userName': 'ascending'}).lean().exec(function(err, data) {
  // process the data
});

或者,您应该能够使用.toObject() 方法将每个模型转换为普通对象,然后对其进行过滤:

var filtered = _.map(data, function(model) {
  return _.omit(model.toObject(), 'password');
});
res.json(filtered);

...但我宁愿使用第一种方法。 )

【讨论】:

  • raina77ow,效果很好,非常感谢!
  • 如果您可以使用 ES6,那么您可以更轻松地做到这一点。让 normalObject = {...data['_doc']}
猜你喜欢
  • 1970-01-01
  • 2016-08-13
  • 2013-07-07
  • 2012-12-05
  • 2017-05-22
  • 2019-07-28
  • 2014-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多