繁体   English   中英

jquery变量范围问题

[英]jquery variable scope problem

我有一个聊天课,有两种方法: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是未定义的。 但是我需要传递房间号以获取正确的状态(状态只是聊天室文本文件中的行数)。

我认为这是变量范围问题或对象上下文中未调用方法的问题。

调用这些方法时,您需要保持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

如果忘记课程,您可能会发现这更容易掌握。 你在那里写的不是一堂课。 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等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM