Javascript jquery变量范围问题

Javascript jquery变量范围问题,javascript,Javascript,我有一个聊天类,有两个方法: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); $.a

我有一个聊天类,有两个方法: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

        },
    });
}
我的问题是在标有XXX的位置调用方法。 在updateChat()方法中,如果我调用像这样的updateChat方法,那么this.room是未定义的。 但我需要传递房间号才能获得正确的状态(状态只是聊天室文本文件中的行数)


我认为变量作用域或对象上下文中未调用的方法存在问题。

调用这些方法时,需要维护
,而不是此:

updateChat();
您可以使用来维护上下文(以便
不会在调用的函数中还原为
窗口
),如下所示:

updateChat.call(this);
$.ajax({
  context: this,
  type: "POST",
  //...rest of your current options/methods
或者调用对象上的方法,如@points所示:

this.update();

还有一个问题,
这个
将不是您想要的
$.ajax()
回调,默认情况下它将是ajax设置对象,因此您需要设置
上下文
选项来维护它,如下所示:

updateChat.call(this);
$.ajax({
  context: this,
  type: "POST",
  //...rest of your current options/methods

如果您忘记了类,您可能会发现这更容易理解。你在那里写的东西不是一门课。JavaScript中没有类。您已经编写了一个构造函数,但它的价值有些可疑,因为您正在为每个实例分别分配成员。构造函数的主要目的是利用原型继承,因此您需要将“方法”分配给构造函数的原型

function Chat (theRoom) {
    this.room = theRoom;
}

Chat.prototype.send = sendChat;
Chat.prototype.update = updateChat;
这样,使用
newchat(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
,等等操心。

非常感谢你,尼克(和卡萨布兰卡)。这就解决了我的问题。如果我早几个小时尝试一下的话-(