从另一个函数中调用 javascript 函数
call a javascript function from within another function
我正在编写一个聊天程序,但我卡在了这部分。
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 函数?
您的函数绑定到 this
对象。如果它是一个全局对象(最顶层的父作用域),那么您可以通过 this.yourfunction
引用 this
中的函数
你必须好好研究 SCOPE 才能理解
问题是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
按照更好的原型继承模型编写代码可能会更好,如下所示:
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);
}
});
};
这通过创建一个真实的 class 解决了上下文问题,例如:
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'
我正在编写一个聊天程序,但我卡在了这部分。
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 函数?
您的函数绑定到 this
对象。如果它是一个全局对象(最顶层的父作用域),那么您可以通过 this.yourfunction
this
中的函数
你必须好好研究 SCOPE 才能理解
问题是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
按照更好的原型继承模型编写代码可能会更好,如下所示:
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);
}
});
};
这通过创建一个真实的 class 解决了上下文问题,例如:
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'