我正在尝试在以下函数中重用名为user
的变量:
UserModel.prototype.authenticate = function (doc, callback) {
// check to see if the username exists
this.users.findOne({ username: doc.username }, function (err, user) {
if (err || !user)
return callback(new Error('username not found'));
// hash the given password using salt from database
crypto.pbkdf2(doc.password, user.salt, 1, 32, function (err, derivedKey) {
if (err || user.password != derivedKey)
return callback(new Error('password mismatch'));
// explicitly define the user object
var user = {
_id: user._id,
type: user.type,
username: user.username,
displayname: user.displayname
};
return callback(err, user);
});
});
};
我尝试重新定义user
回调函数中的pbkdf2
变量。这不像我期望的那样有效。我比较user.password != derivedKey
的行会中断,因为user
在运行时未定义。 user
回调方法参数不应该findOne
仍然是实例吗?如果我将两个user
变量中的任何一个更改为其他变量,它就会起作用。
我可以重命名变量,但这仍然让我感到疑惑。
答案 0 :(得分:5)
问题是,你在函数上下文中声明了一个名为user
的变量:
var user = { };
这将覆盖/重叠由外部函数context声明为形式参数的user
。在 if-statement 之后声明该变量没有帮助。由var
和函数声明声明的变量在分析时被提升,因此事实上,var user
语句放在内部函数的顶部。
答案 1 :(得分:1)
答案是因为hoisting,即使您在其他表达式(users
)中使用变量var users
(user.password != derivedKey
)后声明它,它也会首先解析,保留原始users
引用。
several docs上有hoisting,可能最好对它们采取高峰。