随着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'! };