【问题标题】:Inside Schema method scopes "this" is empty {} in Mongoose 4.4.12在 Mongoose 4.4.12 中,Schema 方法范围内的“this”为空 {}
【发布时间】:2016-08-16 03:17:04
【问题描述】:

当在 Schema 方法中登录到控制台时,对象“this”是“{}”。这发生在一天前,我一直在阅读教程和其他堆栈溢出问题,但我没有找到解决原因的方法。

这是我的模型:

var mongoose    = require("mongoose");
var Schema      = mongoose.Schema;
var constants   = require("../config/constants");
var bcrypt      = require("bcrypt-nodejs");


var UserSchema = new Schema({
    name: String,
    email: String,
    password: String,
    authorization:
    {
        type: Number,
        default: constants.authorization.default
    }
});

UserSchema.pre("save", (next) => {
    var user = this;

    /**
     * Only hash the password when it's been modified or if new.
     */

    // #####################################################
    // ERROR
    // if (!query.isModified("password"))
    //            ^
    // TypeError: query.isModified is not a function
    //
    // user and this == {}
    // ####################################################
    if (!user.isModified("password"))
    {
        return next();
    }

    /**
     * hash password
     */
    bcrypt.hash(user.password, null, null, (err, hash) => {
        if (err)
        {
            return next(err);
        }

        user.password = hash;
        return next();
    });
});

// #####################################################
// ERROR
// user.verifyPassword(req.body.password, match => {
//     ^
// TypeError: user.verifyPassword is not a function
//
// this == {}
// ####################################################
UserSchema.methods.verifyPassword = (reqPassword, callback) => {
    bcrypt.compare(reqPassword, this.password, (err, match) => {
        var e = null;
        var m = match;

        if (err)
        {
            e = err;
            m = false;
        }

        return callback(e, m);
    });
};



module.exports = mongoose.model("User", UserSchema);

这就是我使用它的方式(我已经标记了中断发生的位置)

//includes express, mongoose, User, constants. this part is ok.

/**
 * Authenticates a user post request
 *
 * @request email string
 * @request password string
 *
 */
router.post("/", (req, res) => {
    /**
     * Retrieve the user
     */
    User.find(
    {
        email: req.body.email
    },
    (err, user) =>
    {
        /**
         * An error occurred
         */
        if (err)
        {
            return res.json({
                success:    false,
                message:    "An mongodb error occurred.",
                error:      err
            });
        }

        /**
         * Check for problems with the email or password.
         */
        if (!user)
        {
            return res.json({
                success:    false,
                message:    "Email or password was incorrect."
            });
        }

        // ##########################################################
        // ERROR
        // user.verifyPassword(req.body.password, match => {
        //     ^
        // TypeError: user.verifyPassword is not a function
        // ##########################################################
        user.verifyPassword(req.body.password, match => {
            if (!match)
            {
                return res.json({
                    success:    false,
                    message:    "Email or password was incorrect."
                });
            }

            /**
             * User authenticated!
             */
            req.session.user = user;
            res.json({
                success: true,
                message: "Successfully authenticated."
            });
        });

    });
});

router.get("/", (req, res, next) => {
    var admin = new User({
        name: "admin",
        email: "admin@admin.net",
        password: "admin",
        authorization: constants.authorization.admin
    });

    // ########################################################
    // ERROR
    // if (!user.isModified("password"))
    //            ^
    // TypeError: user.isModified is not a function
    // #######################################################
    admin.save(function(err) {
        if (err)
        {
            console.log(err);
        }

        console.log('User saved successfully');
        res.json({ success: true });
    });
});

有人知道这个问题吗?

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    问题可能与您使用 ES6 箭头语法而不是普通函数作为回调的事实有关。 ES6 箭头函数改变了 this 关键字的语义,这可能会影响 mongoose 在内部处理回调的方式。

    试试

    UserSchema.pre("save", function(next) {
        // ...
    });
    

    而不是

    UserSchema.pre("save", (next) => {
        // ...
    });
    

    【讨论】:

    • 这是我从未猜到的技术!谢谢你,托尼。
    • 哇,节省了我一些时间。谢谢
    • 这里是关于 ES6 github.com/getify/You-Dont-Know-JS/blob/master/… 中的胖箭头函数的深入解释,这个答案正是我在代码中克服这个错误所需要的。
    • 哇!所以我不建议在 Mongoose 中使用箭头功能!
    猜你喜欢
    • 2014-11-23
    • 2023-03-14
    • 2015-04-11
    • 2021-05-13
    • 2023-03-17
    • 2021-02-01
    • 2012-11-05
    • 2014-01-29
    • 2021-09-10
    相关资源
    最近更新 更多