在类方法Javascript中引用类变量

时间:2019-05-26 22:32:13

标签: javascript ecmascript-6

我正在用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));
    }
}

1 个答案:

答案 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