我正在用Javascript定义一个类,用作与iOS兼容的音频播放器。我刚刚开始学习基础知识,并且在尝试访问类方法时遇到问题。
创建了类(var audio = new WebAudio('soundfile.mp3', document.querySelector(#sound_div)
的实例,并尝试访问方法audio.playSound()
之后,我得到:
ReferenceError:找不到变量:第29行的elem
class WebAudio {
constructor(soundFile, elem) {
this.soundFile = soundFile;
this.elem = elem;
}
context() {
var AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
return context;
}
webAudioTouchUnlock(context) {
return new Promise(function (resolve, reject) {
//if AudioContext is suspended, and window has been interacted with
if (context.state === 'suspended' && 'ontouchstart' in window) {
console.log(context.state);
var unlock = function() {
//resume AudioContext (allow playing sound), remove event listeners
context.resume().then(function() {
console.log("context resumed");
this.elem.removeEventListener('touchstart', unlock);
this.elem.removeEventListener('touchend', unlock);
resolve(true);
}, function (reason) {
reject(reason);
});
};
this.elem.addEventListener('touchstart', unlock, false); //error
this.elem.addEventListener('touchend', unlock, false);
} else {
console.log('context not suspended? Context is ' + context.state);
resolve(false);
}
});
}
playSound() {
this.webAudioTouchUnlock(this.context()).then(function (unlocked) {
if(unlocked) {
console.log('playing audio file');
var audio = new Audio('sound/' + soundFile);
if (!audio.playing) {
audio.play();
} else {
audio.pause();
}
}
}, function(reason) {
console.error(reason);
});
document.body.addEventListener('load', playSound(soundFile));
}
}
答案 0 :(得分:2)
将函数传递给事件侦听器后,您将失去与this
的绑定:
var unlock = function() {
//resume AudioContext (allow playing sound), remove event listeners
context.resume().then(function() {
console.log("context resumed");
// this won't point to the instance when called by listener
this.elem.removeEventListener('touchstart', unlock);
this.elem.removeEventListener('touchend', unlock);
resolve(true);
}, function (reason) {
reject(reason);
});
};
this.elem.addEventListener('touchstart', unlock, false); //error
箭头功能或手动调用bind(this)
可以修复它。箭头函数将按词法将this
绑定到函数中,这意味着this
将是定义位置的this
值,而不是如何调用:
var unlock = () => {
//resume AudioContext (allow playing sound), remove event listeners
context.resume().then(() => {
console.log("context resumed");
this.elem.removeEventListener('touchstart', unlock);
this.elem.removeEventListener('touchend', unlock);
resolve(true);
}, function (reason) {
reject(reason);
});
};
this.elem.addEventListener('touchstart', unlock, false); //error