Javascript删除对象属性不起作用

ket*_*sek 12 javascript mean-stack

我正在MEAN.js上运行一些项目,我遇到了以下问题.我想做一些用户的配置文件计算并将其保存到数据库.但是用户模型中的方法存在问题:

UserSchema.pre('save', function(next) {
    if (this.password && this.password.length > 6) {
        this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
        this.password = this.hashPassword(this.password);
    }
    next();
});
Run Code Online (Sandbox Code Playgroud)

如果我将使用我的更改发送密码,它将更改凭据,因此用户下次无法登录.我想在保存之前从用户对象中删除密码,但是我无法做到(让我们看看下面代码中的注释):

exports.signin = function(req, res, next) {
    passport.authenticate('local', function(err, user, info) {
        if (err || !user) {
            res.status(400).send(info);
        } else {
            /* Some calculations and user's object changes */
            req.login(user, function(err) {
                if(err) {
                    res.status(400).send(err);
                } else {
                    console.log(delete user.password); // returns true
                    console.log(user.password); // still returns password :(
                    //user.save();
                    //res.json(user);
                }
            });
        }
    })(req, res, next);
};
Run Code Online (Sandbox Code Playgroud)

怎么了?为什么delete方法返回true,但没有任何反应?谢谢你的帮助 :)

LEM*_*ANE 42

做就是了:

user.password = undefined;
Run Code Online (Sandbox Code Playgroud)

代替:

delete user.password;
Run Code Online (Sandbox Code Playgroud)

并且密码属性不会出现在输出中。

  • @EAT,这家伙并不真的需要删除密码属性。根据他上面的描述,他只是想在输出 JSON 中排除密码的值,只需将密码属性设置为未定义即可解决该问题。尝试一下。 (4认同)
  • 在很多情况下这肯定会导致意想不到的结果 (3认同)
  • @EAT,所以我猜,他需要先 user.save() 然后 user.password = undefined 然后 res.json(user) 。 (3认同)
  • 但为什么删除 user.password 不起作用? (2认同)

San*_*ath 12

与 MONGOOSE 合作?

如果您在使用 Mongoose(Mongo DB 的上层)时遇到此问题,那么您可以在方法lean上使用属性find

例子

没有精益(密钥不会被删除)

const users = await User.find({ role: 'user' }) // no lean method
   users.forEach((user) => {
   delete user.password  // doesn't delete the password
})

console.log(users) 

/* [
    {name:'John', password:'123'}, 
    {name:'Susan', password:'456'}
   ] 
*/ 
Run Code Online (Sandbox Code Playgroud)

随着精益(键被删除)

const users = await User.find({ role: 'user' }).lean() 
   users.forEach((user) => {
   delete user.password   // deletes the password
})

console.log(users) 

/* [
    {name:'John'}, 
    {name:'Susan'}
   ] 
*/ 
Run Code Online (Sandbox Code Playgroud)

精益运作的原因

启用了精简选项的查询返回的文档是纯 JavaScript 对象,而不是 Mongoose 文档。它们没有保存方法、getter/setter、virtuals 或其他 Mongoose 功能。

文档是只读的,因此delete对其不起作用

参考 - /sf/answers/3369596751/ https://mongoosejs.com/docs/api.html#query_Query-lean

方法2 无精益

如果你想在查询时使用 mongoose 提供的方法删除某些属性,可以使用 withselect方法删除,

const users = await User.find({ role: 'user' }).select('-password')

console.log(users)
 /* [
      {name:'John'}, 
      {name:'Susan'}
    ] 
 */ 
Run Code Online (Sandbox Code Playgroud)


Vir*_*dav 10

javascript中有一些删除运算符的规则

  1. 如果属性在"严格模式"下是自己的不可配置属性,则返回false.

例如

x = 42;         // creates the property x on the global object
var y = 43;     // creates the property y on the global object, and marks it as non-configurable

// x is a property of the global object and can be deleted
delete x;       // returns true

// y is not configurable, so it cannot be deleted                
delete y;       // returns false 
Run Code Online (Sandbox Code Playgroud)
  1. 如果对象从原型继承属性,并且没有该属性本身,则无法通过引用该对象来删除该属性.但是,您可以直接在原型上删除它.

例如

function Foo(){}
Foo.prototype.bar = 42;
var foo = new Foo();

// returns true, but with no effect, 
// since bar is an inherited property
delete foo.bar;           

// logs 42, property still inherited
console.log(foo.bar);
Run Code Online (Sandbox Code Playgroud)

所以,请交叉检查这些点,有关更多信息,您可以阅读此链接


小智 8

有类似的问题。这对我有用:

// create a new copy  
let newUser= ({...user}._doc); 

// delete the copy and use newUser that thereafter. 
delete newUser.password; 

Run Code Online (Sandbox Code Playgroud)