[英]Invoke a non-global function from a javascript timer
是否有可能以某种方式从计时器调用非全局函数(即类的方法)?
以下示例显示了我想要实现的目标:
function MyClass() {
var msg = 'no message';
// shows an alert after some delay
this.delayedAlert = function(message) {
msg = message;
// global function works:
//window.setTimeout('globalShow("'+message+'")', 1000);
// this obviously also works:
//this.show();
// this doesn't work: *************
// I'd like to invoke the show() method of this class after some delay
window.setTimeout('this.show()', 2000);
};
this.show = function() {
alert(msg);
};
}
$(document).ready(function() {
$('p').click(function() {
var c = new MyClass();
c.delayedAlert('hello');
});
});
function globalShow(msg) {
$('#hello').html(msg);
}
您可以在此处找到运行示例: http : //jsbin.com/aqako5
function MyClass() {
var msg = 'no message';
// shows an alert after some delay
this.delayedAlert = function(message) {
msg = message;
window.setTimeout($.proxy(this.show, this), 2000);
};
this.show = function() {
alert(msg);
};
}
请使用setTimeout
函数。 字符串称为eval
而eval
类似于goto
。 即猛禽会抓住你。
实际上发生的是在setTimeout函数内部, this
值是默认的this
值,即window。 你需要在代理法通过,使得this
是你想要的this
是。
一个替代图案以正确进行代理this
值是:
function MyClass() {
var msg = 'no message';
var that = this;
// shows an alert after some delay
this.delayedAlert = function(message) {
msg = message;
window.setTimeout(function() {
that.show();
}, 2000);
};
this.show = function() {
alert(msg);
};
}
这涉及在单独的变量中“缓存”正确的this
值。 您仍然不能直接传递that.show
,因为该函数将在不知道this
是什么的情况下被调用。
这会有所帮助。 还可以改善您的课程:如果您的课程未实例化,则可能会引起问题。 如果有人这样叫您的班怎么办:
var myClass = MyClass();
MyClass
内部的this
现在将成为窗口,从而导致各种问题,并将您的属性添加到全局名称空间。
要解决此问题,您需要确保在调用类函数时,它是使用new
运算符完成的。 您需要在MyClass
内部检查,如果这不是MyClass
的新实例,则必须将其强制为新实例。 在下面的代码中,您可以通过以下两种方式之一调用此方法,并使它们都以相同的方式起作用:
var myClass = MyClass();
// or
var myClass = new MyClass();
将您的班级更改为此:
function MyClass() {
// if this isn't an instance, make it so:
if (!(this instanceof MyClass)) {
return new MyClass();
}
var _this = $(this);
var msg = 'no message';
var show = function() {
alert(msg);
};
// shows an alert after some delay
this.delayedAlert = function(message) {
msg = message;
window.setTimeout(show, 2000);
};
}
您也可以通过在每次创建MyClass
实例时不创建新的函数定义来改进此代码。 将您的方法添加到MyClass
的原型中:
(function(window) {
var MyClass = function() {
// if this isn't an instance, make it so:
if (!(this instanceof MyClass)) {
return new MyClass();
}
};
var msg = 'no message';
var show = function() {
alert(msg);
};
MyClass.prototype.delayedAlert = function(message) {
msg = message;
window.setTimeout(show, 2000);
};
window.MyClass = MyClass;
})(window);
您可以声明一个匿名函数:
window.setTimeout(function () {
this.show();
}, 2000);
并且,根据函数的不同,您可以将函数本身传递给setTimeout
:
window.setTimeout(this.show, 2000);
当您将字符串传递给setTimeout
,基本上是在告诉浏览器等待一定时间,然后eval
该字符串。
当浏览eval
的"this.show()"
,它认为this
是指全局对象或window
。
第一条建议使用闭包 ,第二条建议仅传递函数本身(不执行 !),因为在JavaScript中, 函数是一类对象 ,可以像其他任何变量一样对待。
请记住,当您使用第二种解决方案时,您是在将该方法与其上下文分开。 如果您尝试以下操作...
var msg = 'sadface';
var myObj = {
msg: 'hello world',
greet: function () {
alert(this.msg);
}
};
window.setTimeout(myObj.greet, 2000);
...然后, this
greet
将不再引用myObj
。 相反,它将指向window
。 它会提醒sadface
,不是hello world
。
祝好运。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.