困惑于如何编写OO Javascript来实现简单的类模式

时间:2014-09-12 15:03:14

标签: javascript node.js

我确定之前已经问过这个问题,但我完全被OO Javascript迷惑了,所以我甚至无法识别同样的问题。

我正在尝试编写将执行以下常见类型模式的Javascript类:

var User=require('./models').User();

User.findUserById('1', function(err, user) {console.log(user)});


var newUser            = new User();

// set the user's local credentials
newUser.local.email    = 'simon@infoqual.net';
newUser.local.password = newUser.generateHash('hello');

// save the user
newUser.save(function(err) {
    if (err)
        throw err;
    console.log(newUser); //returns undefined for the attributes set above
    return newUser;
});

目前,我的getter属性都没有进入我的内部保存功能。这是我正在写的全班的代码。

exports.User = User;

function User() {
    var user_uuid, local_email, local_password, user=this;

    function generateHash(password) {
        return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
    }

    function validPassword(password, password_compare) {
        return bcrypt.compareSync(password, password_compare);
    }

    function findUserByEmail(email, callback) {
        conn.query("SELECT * FROM users WHERE local_email=$1 LIMIT 1", [email], function (error, result) {
            //var user = this.User;
            if (!error) {
                if (result.rowCount > 0) {
                    local_email = result.rows[0].email;
                    user_uuid = result.rows[0].user_uuid;

                    //load rest of user obj
                    callback(error, user_uuid);
                }


            }
            callback(error, null);

        });


    }

    function findUserById(id, callback) {
        conn.query("SELECT * FROM users WHERE user_uuid='' || $1 LIMIT 1", [id], function (error, result) {
            if (result.rowCount > 0) {
                //update
                user_uuid = result.rows[0].user_uuid;
                local_email = result.rows[0].local_email;
                local_password = result.rows[0].local_password;
                callback(null, user_uuid);
            } else {
                callback(null, null);
            }
        });
    }

    function save(callback) {
        conn.query("SELECT * FROM users WHERE user_uuid='' || $1", [user_uuid], function (error, result) {
            if (error) throw error;
            if (result.rowCount > 0) {
                //update
                conn.query("UPDATE users SET local_email=$1, local_password=$2 WHERE user_uuid=$3", [local_email, local_password, user_uuid], function (error, result) {
                    if (error) throw error;

                    callback(error);
                })
            } else {
                //insert
                conn.query("INSERT INTO users (user_uuid, local_email, local_password) VALUES ($1, $2, $3)", [require('node-uuid').v1(), local_email, local_password], function (error, result) {
                    if (error) throw error;

                    callback(error);
                })
            }
        })
    }

    return {
        user_uuid: user_uuid,

        local: {
            email: local_email,
            password: local_password
        },
        facebook: {
            id: null,
            token: null,
            email: null,
            name: null
        },
        twitter: {
            id: null,
            token: null,
            displayName: null,
            username: null
        },
        google: {
            id: null,
            token: null,
            email: null,
            name: null
        },
        generateHash: generateHash,
        validPassword: validPassword,
        findUserByEmail: findUserByEmail,
        findUserById: findUserById,
        save: save

    }
};

为什么我的内部.save函数无法访问构造函数中设置的local_email和local_password变量?

2 个答案:

答案 0 :(得分:3)

您必须在保存功能中使用this.local.local_email(和密码)。这就是推理:

在您的构造函数中,您有local_emaillocal_password的局部变量 - 这些是您在save函数中访问的变量;调用save时,它会检查本地范围(save自己的范围,由于这些变量不在那里,它会检查下一个范围 - 构造函数范围。

现在,您还拥有返回的对象,该对象具有local.local_email作为属性。调用构造函数时,此属性设置为undefined(如果我正确遵循逻辑)。如果稍后设置,则更改仅发生在该对象的属性上。它不会反映给构造函数的本地local_email

因此,当您在对象的属性上设置新值时,您的函数正在访问局部变量。

答案 1 :(得分:1)

我用这种方式重新编写它似乎工作,但我不完全确定为什么除了说我在前面的例子中我想混合不同风格的JS OO:

var User=new require('./models').User;
var user=new User();

user.findUserById('1', function(err, user) {console.log(user)});


var newUser            = new User();

// set the user's local credentials
newUser.local_email    = 'simon@infoqual.net';
newUser.local_password = newUser.generateHash('hello');

// save the user
newUser.save(function(err) {
    if (err)
        throw err;
    console.log(newUser);

});

这叫:

exports.User = User;

function User() {
    var user=this;
    user.user_uuid=null;
    user.local_email=null;
    user.local_password=null;
    user.generateHash=function (password) {
        return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
    }
    user.validPassword=function (password, password_compare) {
        return bcrypt.compareSync(password, password_compare);
    }
    user.findUserByEmail=function (email, callback) {
        conn.query("SELECT * FROM users WHERE local_email=$1 LIMIT 1", [email], function (error, result) {
            //var user = this.User;
            if (!error) {
                if (result.rowCount > 0) {
                    user.local_email = result.rows[0].email;
                    user.user_uuid = result.rows[0].user_uuid;

                    //load rest of user obj
                    callback(error, user.user_uuid);
                }


            }
            callback(error, null);

        });


    }

    user.findUserById=function (id, callback) {
        conn.query("SELECT * FROM users WHERE user_uuid='' || $1 LIMIT 1", [id], function (error, result) {
            if (result.rowCount > 0) {
                //update
                user.user_uuid = result.rows[0].user_uuid;
                user.local_email = result.rows[0].local_email;
                user.local_password = result.rows[0].local_password;
                callback(null, user.user_uuid);
            } else {
                callback(null, null);
            }
        });
    }

    user.save=function (callback) {
        conn.query("SELECT * FROM users WHERE user_uuid='' || $1", [user.user_uuid], function (error, result) {
            if (error) throw error;
            if (result.rowCount > 0) {
                //update
                conn.query("UPDATE users SET local_email=$1, local_password=$2 WHERE user_uuid=$3", [user.local_email, user.local_password, user.user_uuid], function (error, result) {
                    if (error) throw error;

                    callback(error);
                })
            } else {
                //insert
                user.user_uuid=require('node-uuid').v1();
                conn.query("INSERT INTO users (user_uuid, local_email, local_password) VALUES ($1, $2, $3)", [user.user_uuid, user.local_email, user.local_password], function (error, result) {
                    if (error) throw error;

                    callback(error);
                })
            }
        })
    }
};