2010-11-26 174 views
0

我有两种方法的聊天类:updateChat和sendChat。jquery变量范围问题

//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不确定。 但我需要通过房间号码以获得正确的状态(状态只是聊天室文本文件中的行数)。

我认为这是一个变量作用域的问题,或者在对象上下文中没有调用方法。

回答

2

你需要调用这些方法时保持this,所以不是这样的:

updateChat(); 

您可以使用.call()保持上下文(所以this没有恢复到window被调用的函数里面),这样:

updateChat.call(this); 

或者调用该方法的对象为@casablanca分列如下:

this.update(); 

还有一个多的问题,this不会是你在你的$.ajax()回调想要的东西,这将是阿贾克斯设置默认对象,所以你需要设置context选项来维护它,像这样:

$.ajax({ 
    context: this, 
    type: "POST", 
    //...rest of your current options/methods 
+0

在这种情况下麻烦了,`this.update ()`会工作得很好。 – casablanca 2010-11-26 23:21:08

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

这是为了方便和有用,除非我期待创造非常大量的对象,我不构造函数,newprototype