谷歌关闭:传递'这个'进入window.setInterval

时间:2015-06-29 22:29:26

标签: javascript closures google-closure-compiler google-closure google-closure-library

我有一个模型js文件,看起来像

goog.provide('model.ErrorLogger');
/**
 * @constructor
 */
model.ErrorLogger = function() {
    window.onerror = goog.bind(this.errorHandler, this);
    this.doInitialSend();

};
goog.addSingletonGetter(model.ErrorLogger);

model.ErrorLogger.prototype.ws_ErrLgr_config = true;

model.ErrorLogger.prototype.doInitialSend = function(){
    if (this.ws_ErrLgr_config){
        window.setInterval(this.sendReport, this.ws_ErrLgr_config);
    }   

};

model.ErrorLogger.prototype.sendReport = function(){
    // the value of 'this' needs to be of the ErrorLogger model and not windows
    if (!this.ws_ErrLgr_config || this.stopped) {
          //some more code here
    }
}

在构造函数中,我调用了设置window.setInterval的doInitialSend函数。现在在sendReport函数中,'这个'的值是不正确的。如何正确传递这个'获得正确的价值,而不是获得窗口。 我尝试将其值存储在引用中,但这也没有用。例如

var that = this;
window.setInterval(that.sendReport, that.ws_ErrLgr_config);

3 个答案:

答案 0 :(得分:4)

在Google Closure中执行此操作的惯用方法是使用goog.bind,其优点是可以保证它始终有效。此外,如果可用,它将在引擎盖下使用Function.prototype.bind()

在这种情况下,解决方案将是:

myIntervalInMilliseconds = 1000; // One second.
window.setInterval(goog.bind(this.sendReport, this), myIntervalInMilliseconds);

使用that = this有效,但要求您明确将您的函数包装在另一个函数中,以便在所需函数中将that捕获为this

正如其他答案所指出的那样,使用Function.prototype.bind()要好得多。但是,如果您需要支持旧浏览器(IE< 9),这将无效。

PS:您的代码中的另一个问题是它使用this.ws_ErrLgr_config作为间隔,在原型中设置为true。这是不正确的,您应该选择一个数字来表示您的间隔。

答案 1 :(得分:0)

你可以这样做:

var that = this;
window.setInterval(function() {
    that.sendReport()
}, this.ws_ErrLgr_config.ReportInterval);

这样你可以在正确的上下文中调用sendReport,这也有效:

 window.setInterval(this.sendReport.bind(this), this.ws_ErrLgr_config.ReportInterval);

window.setInterval(that.sendReport, this.ws_ErrLgr_config.ReportInterval)不起作用的原因是因为Javascript是按值传递的。以上陈述相当于:

window.setInterval(function(){
    // the value of 'this' needs to be of the ErrorLogger model and not windows
    if (!this.ws_ErrLgr_config || this.stopped) {
          //some more code here
    }
}, this.ws_ErrLgr_config.ReportInterval);

通过使用.bind()关键字或将其包装在另一个函数中然后从outerscope引用that,您可以在所需的范围内调用该函数。

答案 2 :(得分:0)

或者这个:

window.setInterval((function() {
    this.sendReport();
}).bind(this), this.ws_ErrLgr_config.ReportInterval);