我有一个聊天课,有两种方法:updateChat和sendChat。
//chat.js
var state;
var room;
function Chat (theRoom) {
this.update = updateChat;
this.send = sendChat;
this.room = theRoom;
}
function updateChat(){
alert('ROOM: '+this.room);
$.ajax({
type: "POST",
url: "/chat/process.php",
data: {
'function': 'update',
'state': state,
'room': this.room
},
dataType: "json",
success: function(data){
if(data.text){
for (var i = 0; i < data.text.length; i++) {
$('#chat-area').append($("<p>"+ data.text[i] +"</p>"));
}
}
if(data.state)
state = data.state;
}
});
}
}
//send the message
function sendChat(message, nickname)
{
alert('A'+state); //20
//XXX
updateChat();
alert('B'+state); //20
$.ajax({
type: "POST",
url: "/live-event/chat/process.php",
data: {
'function': 'send',
'message': message,
'nickname': nickname,
'room': this.room
},
dataType: "json",
success: function(data){
alert('C'+state); //wrong!: 2 //it should be 20!
//XXX
updateChat();
alert('D'+state); //21
},
});
}
聊天对象的构造函数:
var chat = new Chat(4); //4 = the number of the chat room
chat.send('test', 'tester');
我的问题是标有XXX的位置的方法调用。 在updateChat()方法中,如果我调用updateChat方法,则this.room是未定义的。 但是我需要传递房间号才能获得正确的状态(状态只是聊天室文本文件中的行数)。
我认为这是变量范围的问题,或者在对象的上下文中没有调用方法。
答案 0 :(得分:2)
调用这些方法时需要维护this
,而不是这样:
updateChat();
您可以使用.call()
来维护上下文(因此this
不会在被调用函数中恢复为window
,如下所示:
updateChat.call(this);
或者在@ casablanca上指出对象上的方法:
this.update();
还有一个问题,this
在你的$.ajax()
回调中不会成为你想要的,它默认是ajax设置对象,所以你需要设置维护它的context
选项,如下所示:
$.ajax({
context: this,
type: "POST",
//...rest of your current options/methods
答案 1 :(得分:0)
如果忘记课程,您可能会发现这更容易掌握。你在那里写的不是一堂课。 JavaScript中没有类。你已经编写了一个构造函数,但它的价值有些可疑,因为你为每个实例分别指定了成员。构造函数的主要目的是利用原型继承,因此您将“方法”分配给构造函数的原型。
function Chat (theRoom) {
this.room = theRoom;
}
Chat.prototype.send = sendChat;
Chat.prototype.update = updateChat;
这样,使用new Chat(r)
创建的每个对象只需要存储房间号,而不需要将这两个方法存储为属性。
或者,只需编写createChatRoom
函数:
var createChatRoom = function(room) {
return {
update: function() {
alert('updating: ' + room);
// ... other stuff
},
sending: function() {
alert('sending: ' + room);
// ... other stuff
}
};
};
其美妙之处可能很明显:您不需要使用this
作为前缀。 room
参数在方法定义的范围内,并且也是真正的私有(除非通过调用方法,否则无法修改。调用者不必记住放置new
。他们只是调用函数并使用两种方法返回一个新对象。
你甚至可以安全地做到这一点:
setTimeout(chatRoom.update, 10);
update
函数“知道”它与哪个对象相关联。永远不需要告诉我使用哪个this
。
这是非常方便和有用的,除非我期望创建非常大量的对象,我不打扰构造函数,new
,prototype
等。