Javascript关闭。为什么我的“this”在这个方法中未定义

时间:2014-03-13 17:01:19

标签: javascript closures

当我运行此代码时,我得到一个TypeError,因为this.coverageList未定义。我怀疑这与我无法看到的关闭问题有关。方法this.accumulateCoverage将传递给forEach()实例的Array方法。

igv.Coverage = function (genomicInterval) {

    this.accumulateCoverage = function (alignment) {

        var i, j, blocksBBoxLength;

        if (!this.coverageList) {

            this.coverageList = new Array(genomicInterval.end - genomicInterval.start);

            for (i = 0; i < this.coverageList.length; i++) {
                this.coverageList[ i ] = 0;
            }

        }

    };

    genomicInterval.features.forEach(this.accumulateCoverage);

}

1 个答案:

答案 0 :(得分:1)

forEach应该将上下文作为第二个参数:

genomicInterval.features.forEach(this.accumulateCoverage, this);

但这可能取决于您是否使用了polyfill。对forEach的支持相对较新,并非所有浏览器都支持。

问题在于,当您传递函数引用时,它会丢失与其所属对象的任何关联。它只是一个功能。只有当您使用object.method()语法调用该函数时,该函数才会接收隐式this参数(分配给object)。这就是为什么作为输入并执行另一个函数的函数通常允许您提供应该作为this传递的对象。

可能适合您目的的替代模式是将this分配给函数外部的局部变量,以便它包含在函数闭包中。

igv.Coverage = function (genomicInterval) {
    var me = this;    
    function accumulateCoverage(alignment) {
        var i, j, blocksBBoxLength;

        if (!me.coverageList) {
           //...
        }
    };

    genomicInterval.features.forEach(accumulateCoverage);
}

这消除了像在第一个解决方案中那样传递上下文的需要。