Javascript 在原型方法中从内部函数修改实例变量
我试图在服务器端JavaScript(节点)中将数据库中的数据建模为“类”。 目前,我只是在适当的地方使用传统的构造函数模式和原型方法,并将构造函数函数公开为整个Javascript 在原型方法中从内部函数修改实例变量,javascript,oop,scope,Javascript,Oop,Scope,我试图在服务器端JavaScript(节点)中将数据库中的数据建模为“类”。 目前,我只是在适当的地方使用传统的构造函数模式和原型方法,并将构造函数函数公开为整个模块.exports。事实上,这是服务器端对于问题的核心并不重要,但我想我会提供它作为参考 代码的问题区域如下所示: User.prototype.populate = function() { var that = this; db.collection("Users").findOne({email :
模块.exports
。事实上,这是服务器端对于问题的核心并不重要,但我想我会提供它作为参考
代码的问题区域如下所示:
User.prototype.populate = function() {
var that = this;
db.collection("Users").findOne({email : that.email}, function(err, doc){
if(!err) {
that.firstName = doc.firstName;
that.lastName = doc.lastName;
that.password = doc.password;
}
console.log(that); //expected result
});
console.log(that); //maintains initial values
};
无论何时调用此函数,只要findOne()
完成,对对象的更改就不会持续。我意识到this
的作用域更改为具有新函数作用域的全局对象,因此我将其引用保持为this
。如果从匿名函数中选择console.log(that)
,则数据将按预期显示在其属性中。但是,如果我在函数完成后记录该,它将保持函数开始时的状态
这里发生了什么,我如何按照预期更改实例变量
“但是,如果我在函数完成后记录,…”
我猜你是在做这样的事
var user = new User
user.populate();
console.log(user);
如果是这样的话,console.log
将在调用对.findOne()
的异步回调之前很久运行
任何依赖于findOne
响应的代码都需要在回调中调用
User.prototype.createNickName = function () {
this.nickname = this.firstName.slice(0,3) + '_' + this.lastName.slice(0,3);
};
// >>>------------------------------v----receive a function argument...
User.prototype.populate = function(callback_func) {
var that = this;
db.collection("Users").findOne({email : that.email}, function(err, doc){
if(!err) {
that.firstName = doc.firstName;
that.lastName = doc.lastName;
that.password = doc.password;
}
// all users will have the "createNickName()" method invoked
that.createNickName();
// ...and invoke it in the callback.
callback_func.call(that);
// By using .call(), I'm setting the "this" value
// of callback_func to whatever is passed as the first argument
});
};
编辑:您的更新与我上面的示例略有不同,但原因相同 将回调传递给
findOne
方法的全部原因是它执行异步活动。如果没有,就没有理由回调。您只需将内部代码直接放在调用findOne
之后,就像使用console.log()
一样
但由于它是异步的,后续代码不会等待执行。这就是为什么要在控制台中获取未填充的对象
如果将标签添加到每个console.log()
因此,观察console.log
调用的顺序就可以清楚地看到,空的调用发生在回调中的调用之前
User.prototype.createNickName = function () {
this.nickname = this.firstName.slice(0,3) + '_' + this.lastName.slice(0,3);
};
// >>>------------------------------v----receive a function argument...
User.prototype.populate = function(callback_func) {
var that = this;
db.collection("Users").findOne({email : that.email}, function(err, doc){
if(!err) {
that.firstName = doc.firstName;
that.lastName = doc.lastName;
that.password = doc.password;
}
// all users will have the "createNickName()" method invoked
that.createNickName();
// ...and invoke it in the callback.
callback_func.call(that);
// By using .call(), I'm setting the "this" value
// of callback_func to whatever is passed as the first argument
});
};
EDIT:您还可以让.populate()
方法接收在.findOne
回调中调用的回调
User.prototype.createNickName = function () {
this.nickname = this.firstName.slice(0,3) + '_' + this.lastName.slice(0,3);
};
// >>>------------------------------v----receive a function argument...
User.prototype.populate = function(callback_func) {
var that = this;
db.collection("Users").findOne({email : that.email}, function(err, doc){
if(!err) {
that.firstName = doc.firstName;
that.lastName = doc.lastName;
that.password = doc.password;
}
// all users will have the "createNickName()" method invoked
that.createNickName();
// ...and invoke it in the callback.
callback_func.call(that);
// By using .call(), I'm setting the "this" value
// of callback_func to whatever is passed as the first argument
});
};
没错。尽管这种情况在外部调用日志记录user.populate()中以及在populate()方法本身中都会发生(但不在findOne()的范围内)。我已经更新了帖子以反映我的意思。@user574930:刷新浏览器。我已经更新了我的答案。那么,有了这些知识,我如何才能实现我正在寻找的效果,在哪里我可以简单地调用populate()方法并知道对象的属性将得到更新?通过传递更多回调-如果你想在属性更新时呈现页面,将其放入一个函数中,并将其传递到链中,然后在db.collection回调中调用它。@DuxPrime:好吧,您需要将您的代码流视为转移到传递给findOne
的回调中。因此,在这里,您将继续您的编码。此外,重要的是要记住,函数(因此函数)可以像任何其他数据一样传递。