2010-11-26 8 views
0

私はチャットクラスにupdateChatとsendChatという2つのメソッドがあります。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(); 

あなたはこのように、(そうthisが呼び出される関数の内部windowに戻りません)コンテキストを維持するために.call()を使用することができます:

updateChat.call(this); 

またはOUT以下casablancaポイント@としてオブジェクトのメソッドを呼び出します。

this.update(); 

ももう一つの問題は、thisは、それはあなたがそれを維持するためにcontextオプションを設定する必要がありますので、アヤックスの設定は、デフォルトでオブジェクトになるだろう、あなたは$.ajax()コールバックで欲しいものがあるではありませんこのように:

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

など、私は、オブジェクトの非常に大量に作成するために期待していない限り、私はコンストラクタ関数、newprototypeを気にしないので、便利かつ有用です() 'も同様にうまくいくでしょう。 – casablanca

+0

@casablanca - +1 - yupも真ですが、 –

+0

を含めて更新させていただきます。ありがとう、ニック(とカサブランカ)。それが私の問題を解決しました。もし私が数時間前にそれを試してみたら、 :-( – user478419

0

クラスを忘れた場合は、これを理解するのが簡単です。あなたがそこに書いたことは、クラスではありません。 JavaScriptにはクラスはありません。あなたはコンストラクタ関数を書いていますが、インスタンスごとにメンバを個別に割り当てるので、やや疑わしい値です。コンストラクタ関数の主な目的は、プロトタイプ継承を利用することです。そのため、コンストラクタ関数のプロトタイプに「メソッド」を割り当てます。

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

Chat.prototype.send = sendChat; 
Chat.prototype.update = updateChat; 

そのように、new Chat(r)で作成された各オブジェクトは、部屋番号を格納する必要があります、およびプロパティのような2つのメソッドを格納する必要はありません。

また、ちょうどcreateChatRoom関数を書く:

var createChatRoom = function(room) { 

    return { 
     update: function() {  
      alert('updating: ' + room); 
      // ... other stuff 
     }, 

     sending: function() {  
      alert('sending: ' + room); 
      // ... other stuff 
     } 
    }; 
}; 

ことの美しさは、おそらく明白です:あなたはthisで何かをプレフィックスする必要はありません。 roomパラメータはメソッド定義の範囲内にあり、実際にはプライベートでもあります(メソッドの呼び出し以外では変更できません)。呼び出し側はnewを覚えておく必要はありません。その中に2つのメソッドを持つオブジェクト。

あなたも安全にこれを行うことができます:

setTimeout(chatRoom.update, 10); 

update機能を、それが関連しているものを対象「知っています」。どのようなthisを使用するかについて言及する必要はありません。

これはthis.update `、この場合

関連する問題