Javascript:回调中的变量范围?

时间:2016-10-23 14:07:13

标签: javascript scope callback ecmascript-6

我在回调中遇到变量范围问题。这有点难以解释,所以这里是我正在使用的简化代码。请注意,我正在使用ES6。

class Foo {
    constructor() { /* ... */ }

    // Execute 'callback' after 'delay' has passed (works fine)
    timer(delay, callback) { /* ... */ }

    // Emit a sound of 'frequency' for 'duration' (works fine)
    sound(duration, frequency) { /* ... */ }

    // Play each 'frequency' for 'duration'
    music(duration, frequencyArray) {
        var that = this;
        for (var i = 0; i < frequencyArray.length; i++) {
            var freq = frequencyArray[i];
            this.timer(duration*i, function() {
                // The line below doesn't work properly
                // 'freq' is always equal to the last value of the array
                that.sound(duration, freq); 
            });
        }
    }
}

// Usage
var F = new Foo();
F.music(200, [150, 200, 250]);

在上面的示例中,我没有听到3个不同的音符(150,200,250),而是听到频率为250的相同音符的3倍。

我理解为什么(实际调用回调时var freq等于250,但我不知道如何解决这个问题。有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

当您在循环中使用延迟回调时,您必须为此调用创建一个特殊范围。 要做到这一点,你有两个主要的解决方案:在你的类中创建一个函数或者像本地匿名函数(function(localVar){/ *使用传递给这个匿名函数的局部变量来运行你的延迟回调* /})(localVar) ;

这可以通过回调使用循环的范围,每个循环的si,变量的值变化以及调用回调时的变量来解释,变量具有最后一个值。