以下代码创建了一个在 500 毫秒后停止的音调。这非常简单:
// Create audio context and nodes
var audioContext = new AudioContext();
var oscillator = audioContext.createOscillator();
oscillator.type = 'sine';
oscillator.frequency.value = 250;
// Attach nodes and start tone
oscillator.connect(audioContext.destination);
oscillator.start();
// Stop the tone after half a second
window.setTimeout(function() {
oscillator.stop();
}, 500);
但是当我重构对 oscillator.stop() 的调用以简单地将函数指针传递给 window.setTimeout
时,它不再有效 - 至少在 Chrome 中:
window.setTimeout(oscillator.stop, 500); // throws 'Illegal Invocation' exception
这最初让我感到困惑 - 调用之间唯一真正的区别是在第二个调用中没有 this
绑定(bind)到 oscillator
。显式绑定(bind) this
确实解决了这个问题:
window.setTimeout(oscillator.stop.bind(oscillator), 500); // works perfectly
这是否应该是 AudioBufferSourceNode.stop()
需要调用的方式(使用“this”上下文),或者这只是 Chrome 实现中的一个缺点(可能会依赖 JS而不是直接调用 native 代码)?我是否应该假定所有 BOM 方法都需要 this
绑定(bind)?
最佳答案
是的,一般来说,绑定(bind)是必要的。有了这个:
setTimeout(oscillator.stop, 500);
只有 stop()
被引用为一个独立的方法/函数,而不是它所属的“上下文”,所以当它被调用时 stop()
期望 oscillator
作为上下文 (this
) 但获取 window
当然会失败。
调用 native 代码的方法也需要进行适当的绑定(bind),因为它们是通过 JavaScript 公开的。一个不同的例子是:
var getId = document.getElementById;
getId("someId"); // will fail
鉴于
var getId = document.getElementById.bind(document);
getId("someId"); // will work
所以这里需要绑定(bind)
关于javascript - AudioBufferSourceNode.stop() 是否需要 'this' 绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30687353/