欢迎光临

木子屋

标题: 构造函数中使用setTimeout引发的问题

作者: dnawo

日期: 2009-07-22 09:23 AM

分类: 脚本语言

内容: 今天写了段脚本，结果执行出错，脚本内容大致如下：
复制内容到剪贴板 程序代码function Class1()
{
this.i = 0;
this.Add = function()
{
this.i++;
setTimeout(this.Add,1000);
}
}
var o = new Class1();
o.Add();
调试了好久，猜测是this的问题，修改了下代码：
复制内容到剪贴板 程序代码function Class1()
{
this.i = 0;
this.Add = function()
{
if(this instanceof Class1)alert("Class1");
if(this == window)alert("window");
this.i++;
setTimeout(this.Add,1000);
}
}
var o = new Class1();
o.Add();
第一次提示"Class1"，第二次提示"window"，随即脚本出错。为了说明问题，将脚本分解执行：
复制内容到剪贴板 程序代码/*
第一部分
*/
function Class1()
{
this.i = 0;
this.Add = function()
{
this.i++;
}
}
var o = new Class1();
o.Add();
/*
第二部分
*/
//此处用调用普通函数的方式调用构造函数，构造函数中的this指的是window对象[1]
//this.i++后this.i的值为NaN，因window对象没有Add方法脚本出错
setInterval(function(){this.i++;setTimeout(this.Add,1000);},1000);
正确的脚本：
复制内容到剪贴板 程序代码function Class1()
{
var _me = this;
this.i = 0;
this.Add = function()
{
this.i++;
setTimeout(function(){_me.Add();},1000);
}
}
var o = new Class1();
o.Add();
相当于：
复制内容到剪贴板 程序代码function Class1()
{
var _me = this;
this.i = 0;
this.Add = function()
{
this.i++;
}
}
var o = new Class1();
setInterval(function(){o.Add();},1000);
2009-07-23 借助闭包实现：
复制内容到剪贴板 程序代码//闭包含数
Function.prototype.bind = function(obj) {
var method = this;
return function() {
return method.apply(obj, arguments);
};
}
function Class1()
{
var _me = this;
this.i = 0;
this.Add = function()
{
this.i++;
alert(this.i);
setTimeout(_me.Add.bind(_me),1000);
}
}
var o = new Class1();
o.Add();
《JavaScript权威指南》第五版P936：
setTimeout(code,delay)，当code执行的时候，它是在Window对象的环境中执行的。如果code是一个函数，Window对象就是this关键字的值。如果code是一个字符串，它是在全局作用域中执行的，而Window对象是作用域链上唯一的对象。即便setTimeout()的调用发生在一条长长的作用域链上的一个函数之中，这也是成立的。
参考
[1]. 再说Js构造函数：http://www.mzwu.com/article.asp?id=2145

+ 查看当前日志评论 (0)

登录

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 0.941 ms

返回

标题: 构造函数中使用setTimeout引发的问题

你没有权限发表评论

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 0.941 ms

返回

暂无评论

返回

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 0.973 ms

返回