Ссылка на переменную класса в методе класса Javascript

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

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

ReferenceError: Can't find variable: elem on line 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.info(context.state);
           var unlock = function() {
               //resume AudioContext (allow playing sound), remove event listeners
               context.resume().then(function() {
                   console.info("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.info('context not suspended? Context is ' + context.state);
               resolve(false);
           }
       });
    }

    playSound() {
        this.webAudioTouchUnlock(this.context()).then(function (unlocked) {
            if (unlocked) {
                console.info('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));
    }
}

Какой пример ввода? Какие аргументы вы бы передали new WebAudio?

Jack Bashford 27.05.2019 00:39

@JackBashford спасибо за ответ, вопрос об использовании. "var audio = новый WebAudio('soundfile.mp3', document.querySelector(#sound_div)"

froggomad 27.05.2019 00:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы теряете привязку к this, когда передаете функцию прослушивателю событий:

var unlock = function() {
               //resume AudioContext (allow playing sound), remove event listeners
               context.resume().then(function() {
                   console.info("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.info("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 

Спасибо, теперь получаю TypeError: undefined is not a object (оценка this.elem) — webAudio.js:29 — audio.elem содержит правильную ссылку

froggomad 27.05.2019 00:47

@froggomad извините, здесь много вложенных функций. Вероятно, вам также нужно определить обратный вызов Promise с помощью функции стрелки: return new Promise((resolve, reject) => {...

Mark 27.05.2019 00:52

Спасибо, вы ведете меня по правильному пути... без вас я бы не справился. Нужен this.webAudioTouchUnlock(this.context()).then( (unlocked) => в playSound() и отдельная функция для добавления слушателя

froggomad 27.05.2019 01:38

Круто, рад, что ты понял @froggomad.

Mark 27.05.2019 01:38

Другие вопросы по теме