随着JavaScript编码技术和设计模式多年来变得越来越复杂,回调和闭包中的自引用作用域也相应增加,这是造成JavaScript问题的 "this/that 混乱 "的一个相当普遍的来源。
考虑下面代码:
Game.prototype.restart = function () {this.clearLocalStorage();this.timer = setTimeout(function() {this.clearBoard(); // What is "this"?}, 0);
};
执行上述代码会出现以下错误:
Uncaught TypeError: undefined is not a function
上述错误的原因是,当调用 setTimeout()
时,实际上是在调用 window.setTimeout()
。因此,传递给setTimeout()
的匿名函数是在window
对象的上下文中定义的,它没有clearBoard()
方法。
传统的、符合老式浏览器的解决方案是将 this
引用保存在一个变量中,然后可以被闭包继承,如下所示:
Game.prototype.restart = function () {this.clearLocalStorage();var self = this; // Save reference to 'this', while it's still this!this.timer = setTimeout(function(){self.clearBoard(); // Oh OK, I do know who 'self' is!}, 0);
};
另外,在较新的浏览器中,可以使用bind()
方法来传入适当的引用:
Game.prototype.restart = function () {this.clearLocalStorage();this.timer = setTimeout(this.reset.bind(this), 0); // Bind to 'this'
};Game.prototype.reset = function(){this.clearBoard(); // Ahhh, back in the context of the right 'this'!
};