Ссылка на переменную класса в методе класса Javascript - PullRequest
0 голосов
/ 27 мая 2019

Я определяю класс в Javascript, предназначенный для использования в качестве аудиоплеера, совместимого с iOS.Я только начинаю с основ и сталкиваюсь с проблемой при попытке доступа к методу класса.

После создания экземпляра класса (var audio = new WebAudio('soundfile.mp3', document.querySelector(#sound_div)) и попытки доступа к методу audio.playSound() Я получаю:

ReferenceError: Не могу найти переменную: elem в строке 29

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 Ответ

2 голосов
/ 27 мая 2019

При передаче функции прослушивателю событий вы теряете привязку к 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...