سؤال

When I run this code I get a TypeError because this.coverageList is undefined. I suspect this has to do with a closure issue I can't see. The method this.accumulateCoverage is passed to the forEach() method of an Array instance.

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);

}
هل كانت مفيدة؟

المحلول

forEach should take a context as the second argument:

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

But this may depend on whether you're using a polyfill. Support for forEach is relatively new, and may not be supported in all browsers.

The issue is that when you pass a function reference, it loses any association with the object it belongs to. It's just a function. It is only when you invoke the function using object.method() syntax that the function receives the implicit this argument (assigned to object). That's why functions that take as input and execute another function usually allow you to provide the object that should be passed as this as well.

An alternative pattern that might suit your purpose is to assign this to a local variable outside of your function, so that it is included in the function closure.

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

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

    genomicInterval.features.forEach(accumulateCoverage);
}

This negates the need to pass around contexts like in the first solution.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top