我正在编写一个聊天程序,但我被困在这一部分。
var Controller=function conversation() {
this.createMessageNode=function(msg,sender,time,mid){
var newMessage;
if(sender==sessionStorage.getItem('userid')){
newMessage="<div class='message-sent' id='"+mid+"'>"+msg+"<span class='time'>"+time+"</span></div>";
}else{
newMessage="<div class='message-recv' id='"+mid+"'>"+msg+"<span class='time'>"+time+"</span></div>";
}
sessionStorage.setItem('lastMessage',mid);
$('.chat-messages').append(newMessage);
}
this.getMessages=function(){
if(sessionStorage.getItem('lastMessage')==null){
sessionStorage.setItem('lastMessage',0);
}
$.ajax({url:"getmessages.php",type:"POST",data:{last:sessionStorage.getItem('lastMessage'),cid:sessionStorage.getItem('conversationid')},success:function(result) {
var messages=JSON.parse(result);
for (var i = 0; i < messages.length; i++) {
createMessageNode(messages[i].message,messages[i].sender,messages[i].time,messages[i].mid);
var cont=document.getElementById('chat-messages');
cont.scrollTop=cont.scrollHeight;
};
}});
}
}
现在,当我这样做时,它显示错误
Uncaught ReferenceError: createMessageNode is not defined
现在在for循环中“this”变量指的是ajax对象。我怎样才能调用createMessageNode函数?
答案 0 :(得分:1)
您的函数绑定到this
对象。如果它是全局对象(最顶层的父作用域),那么您可以通过this
this.yourfunction
中的函数
您必须正确学习SCOPE才能理解
答案 1 :(得分:0)
问题是createMessageNode()
是Controller
对象实例的一种方法,因此您需要在调用它时引用该实例。在没有引用实例的情况下,JavaScript引擎正在寻找当前范围内的函数,然后是每个更高的范围,直到全局范围。
通常您会使用this
关键字来引用该实例,但在您的情况下,jQuery ajax调用已更改this
上下文,因此您无法直接使用this
可能的解决方案是,在ajax调用之前,存储this
上下文:
var that = this;
现在,在ajax成功函数中:
that.createMessageNode(messages[i].message,messages[i].sender,messages[i].time,messages[i].mid);
^^ refer to the instance
答案 2 :(得分:0)
在更好的原型继承模型之后编写代码可能会更好,例如:
function Controller() {
this.chatMessages = $('.chat-messages');
}
Controller.prototype.createMessageNode = function (msg, sender, time, mid) {
var newMessage;
if (sender == sessionStorage.getItem('userid')) {
newMessage = "<div class='message-sent' id='" + mid + "'>" + msg + "<span class='time'>" + time + "</span></div>";
} else {
newMessage = "<div class='message-recv' id='" + mid + "'>" + msg + "<span class='time'>" + time + "</span></div>";
}
sessionStorage.setItem('lastMessage', mid);
this.chatMessages.append(newMessage);
};
Controller.prototype.getMessages = function () {
var _this = this;
if (sessionStorage.getItem('lastMessage') === null) {
sessionStorage.setItem('lastMessage', 0);
}
$.ajax({
url: "getmessages.php",
type: "POST",
data: {
last: sessionStorage.getItem('lastMessage'),
cid: sessionStorage.getItem('conversationid')
},
success: function (result) {
var messages = JSON.parse(result);
for (var i = 0; i < messages.length; i++) {
_this.createMessageNode(messages[i].message, messages[i].sender, messages[i].time, messages[i].mid);
}
var cont = $('#chat-messages');
cont.scrollTop(cont.scrollHeight);
}
});
};
这通过创建一个真正的类来解决上下文的问题,例如:
var conversation = new Controller();
conversation.getMessages();
conversation.createMessageNode('Hello, World!', 'JimmyBoh', new Date(), 8268124);
此外,每当你有嵌套函数时,它可以帮助将所需的上下文存储在局部变量中,例如_this
或that
等。这是一个更简单的例子:
function outer() {
// Temporarily store your desired context.
var _this = this;
// Make any call that executes with a different context.
$.ajax({
url: "getmessages.php",
type: "GET",
success: function inner(result) {
_this.doSomething(result);
}
});
};
最后,您可能希望在与当前不同的上下文中执行方法。 .call()
和.apply()
可用于运行具有指定上下文和参数的方法。例如:
function printThis() {
console.log(this.toString());
console.dir(arguments);
}
printThis.call('Hello, World!');
printThis.call('Call array:', [2, 4, 6, 8], 10); // Keeps arguments as-is.
printThis.apply('Apply array:', [2, 4, 6, 8], 10); // Accepts an array of the arguments.
function Sum(startingValue) {
this.value = startingValue || 0;
}
Sum.prototype.add = function (number) {
this.value += number;
}
var realSum = new Sum(2);
var fakeSum = {
value: 3
};
realSum.add(1);
Sum.prototype.add.call(fakeSum, 2);
console.log(fakeSum.value); // Prints '5'
console.log(realSum.value); // Prints '3'