Почему функция работает при объявлении переменной глобально, но не с помощью var - PullRequest
0 голосов
/ 24 февраля 2019

Я хотел бы объявить свойство soundFileName как var soundFileName = 'audio/60.wav';, чтобы soundFileName не определялось глобально, но когда я это получаю, я получаю ReferenceError: soundFileName is not defined.

Я передаю значение soundFileName в качестве параметра в loop(soundFileName), и я думаю, что значение 'audio/60.wav' должно пройти очень хорошо.

Я подозреваю, что это как-то связано с областью действия или вложенностью, но я не уверен, как решить проблему.Код работает, когда я использую soundFileName = 'audio/60.wav'; без вар.

Чего мне не хватает?Спасибо!

РЕДАКТИРОВАТЬ: код работает и обновляется!

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

  <script src="js/howler.core.js"></script>
  <link rel="stylesheet" href="css/styles.css">

</head>

<body>

  <script src="timeprobabilities.js"></script>

  <script>
    ///////////////////////////////////////////////////////////////
    // MASTER START ///////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////

    // initiates fist call to all clocks to each will start and can then be called again

    (function masterStart() {
      setTimeout(function() {
        //// LOOP SOUNDS \\\\
        A();
      }, 0);
    }());

    ///////////////////////////////////////////////////////////////
    // LOOPS SHARED OPTIONS ///////////////////////////////////////
    ///////////////////////////////////////////////////////////////

    var options = {
      numberOfSounds: 0,
      maxNumberOfSounds: 4
    };

    function logNumberOfSounds() { // passing options into this before is what broke code
      options.numberOfSounds++;
      //console.log('Number of sounds is: ' + options.numberOfSounds + '########');
    }

    ///////////////////////////////////////////////////////////////
    // LOOP A  ////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////

    function A() {
      var optionsA = {
        playDurationMin: 0,
        playDurationMax: 60000,
        // start time minimum and maximum
        startMinA: 0,
        startMaxA: 8000,
        maxVolumeA: 1,
        //
        startMinB: 0,
        startMaxB: 30000,
        maxVolumeB: 1,
        //
        startMinC: 0,
        startMaxC: 30000,
        maxVolumeC: 1,
        //
        startMinD: 0,
        startMaxD: 30000,
        maxVolumeD: 1,
        //
        startMinE: 0,
        startMaxE: 30000,
        maxVolumeE: 1,
        //
        startMinF: 0,
        startMaxF: 30000,
        maxVolumeF: 1,
        //
        startMinG: 0,
        startMaxG: 30000,
        maxVolumeG: 1,
        //
        startMinH: 0,
        startMaxH: 30000,
        maxVolumeH: 1,
        //
        startMinI: 0,
        startMaxI: 30000,
        maxVolumeI: 1,
        //
        startMinJ: 0,
        startMaxJ: 30000,
        maxVolumeJ: 1,
        //
        startMinK: 0,
        startMaxK: 30000,
        maxVolumeK: 1
      };

      masterClock();

      function masterClock() {
        setTimeout(function() {
          soundA(options, optionsA);
        }, 10); // these need to be called with delay so they don't use the other functions' paramaters
      }

      function soundA() {

        var soundFileName = 'audio/60.wav';
        fadeIn = 8000;
        fadeOut = 8000;

        console.log('soundFileName in A: ' + soundFileName);

        calculateStartDelay(optionsA.startMinA, optionsA.startMaxA);

        function calculateStartDelay(startMin, startMax) {
          startDelay = Math.floor(Math.random() * startMax) + startMin;
        }

        function calculatePlayDuration(playDurationMin, playDurationMax) {
          playDuration = Math.floor((Math.random() * playDurationMax) + playDurationMin);
        }

        function executePlayTools() {
          calculatePlayDuration(optionsA.playDurationMin, optionsA.playDurationMax);
          loop(options, playDuration, soundFileName, fadeIn, fadeOut);
          console.log('A: ////////////////////////////////// ');
          masterClock();
        }

        setTimeout(function() {
          if (probabilityValue < probabilityPointA) {
            maxVolume = optionsA.maxVolumeA;
            executePlayTools();
          } else if (probabilityValue < probabilityPointB) {
            maxVolume = optionsA.maxVolumeB;
            executePlayTools();
          } else if (probabilityValue < probabilityPointC) {
            maxVolume = optionsA.maxVolumeC;
            executePlayTools();
          } else if (probabilityValue < probabilityPointD) {
            maxVolume = optionsA.maxVolumeD;
            executePlayTools();
          } else if (probabilityValue < probabilityPointE) {
            maxVolume = optionsA.maxVolumeE;
            executePlayTools();
          } else if (probabilityValue < probabilityPointF) {
            maxVolume = optionsA.maxVolumeF;
            executePlayTools();
          } else if (probabilityValue < probabilityPointG) {
            maxVolume = optionsA.maxVolumeG;
            executePlayTools();
          } else if (probabilityValue < probabilityPointH) {
            maxVolume = optionsA.maxVolumeH;
            executePlayTools();
          } else if (probabilityValue < probabilityPointI) {
            maxVolume = optionsA.maxVolumeI;
            executePlayTools();
          } else if (probabilityValue < probabilityPointJ) {
            maxVolume = optionsA.maxVolumeJ;
            executePlayTools();
          } else {
            maxVolume = optionsA.maxVolumeK;
            console.log('Probability Else');
          }
          console.log('startDelay: ' + startDelay)
        }, startDelay);
      }
    }

    ///////////////////////////////////////////////////////////////
    // SHARED LOOP  ///////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////

    function loop(options, playDuration, soundFileName, fadeIn, fadeOut) {

      console.log('soundFileName in loop: ' + soundFileName);

      if (options.numberOfSounds < options.maxNumberOfSounds) { //Don't create more than the max number of sounds.

        var sound = getSound(soundFileName);
        var id2 = sound.play();

        logNumberOfSounds();

        sound.volume(0); // don't think I need this since it's declared above and in getSound(), but it stops blips?
        sound.fade(0, maxVolume, fadeIn, id2); // FADE IN

        setTimeout(function() {
          sound.fade(maxVolume, 0, fadeOut, id2); // FADE OUT
          options.numberOfSounds--;

          // Attempt to clean up the sound object
          setTimeout(function() {
            sound.stop();
            sound.unload();
          }, fadeOut + 1000);
        }, playDuration);
      }

    }

    // PLAYER FOR MAIN SOUND FUNCTION /////////////////////////////
    function getSound(soundFileName) {
      return new Howl({
        src: [soundFileName],
        autoplay: true,
        loop: true,
        volume: 0,
        fade: 0 // removes the blip
      });
    }
  </script>

  <script src="js/howler.core.js"></script>
  <script src="js/siriwave.js"></script>
  <script src="js/player.js"></script>

</body>

</html>

Ответы [ 3 ]

0 голосов
/ 24 февраля 2019

Вы неправильно используете значение переменной.Его значение определяется внутри функции soundA(), а затем передается функции loop(), у которой нет никакого способа узнать, какая переменная есть какая.

Есть два решения этой проблемы.Либо задайте предварительно определенные имена параметров, например function loop(options, options, playDuration, soundFileName, fadeIn, fadeOut){...}, затем используйте эти имена в теле функции, либо вы можете использовать функциональный объект arguments.Объект arguments - это массивоподобный объект, созданный для каждой функции (за исключением функций со стрелками), который содержит все переданные им параметры, с помощью которых вы можете легко использовать переданные ему переменные.См. Пример ниже:

loop(options, playDuration, soundFileName, fadeIn, fadeOut);

function loop() {
          console.log('soundFileName in loop: ' + arguments[2]); //The arguments object will contain all five parameters passed to the function call. 
}

Сказав, что использование неизвестного количества параметров для функций считается плохой практикой, так как это может привести к большему количеству ошибок и ошибок, чем при использовании предопределенных параметров.Тем не менее, в вашем распоряжении есть объект arguments, и вы можете структурировать свое приложение так, как хотите.Просто помните, что кто-то еще может прочитать код и запутаться в этом.

Кроме того, после решения этой проблемы я столкнулся с еще одним: вы используете функцию в отдельном теге сценария, который предшествует объявлению фактической функции, что приводит к ошибке undefined.

Кроме того, пометьте этот ответ как решение, чтобы помочь другим проходящим мимо.

РЕДАКТИРОВАТЬ # 1: Начиная с ES6 +, вы можете указывать значения параметров по умолчанию на тот случай, если вы хотите всегда сохранятьФункция ведет себя, как и ожидалось, даже если значения не переданы должным образом.

EDIT # 2: Как @nikolairiedel упомянул в комментариях, функция getSound() находится вне области объявления этой переменной, поэтому не может получить ее значение.Вы можете установить параметр для этой функции и / или указать значение параметра по умолчанию, чтобы убедиться, что он работает все время, как указано выше в правке № 1.

0 голосов
/ 24 февраля 2019

Каждая функция имеет свою собственную область, и переменные , объявленные внутри функции, существуют только в области действия этой функции .

В этом случае soundFileName объявляется как var вsoundA так что он существует только в пределах soundA.

Вы передаете soundFileName в качестве аргумента loop, и оттуда вы передаете его getSound, но ваш определения функций для loop и getSound не включают никаких именованных параметров.

Вам необходимо изменить определение функции для loop и getSound навключают ожидаемые параметры:

function loop(options, playDuration, soundFileName, fadeIn, fadeOut) {
  ...
  // soundFileName is now availabie in this scope
  ...
}


function getSound(soundFileName) {
  ...
  // soundFileName is now availabie in this scope
  ...
}

Обратите внимание, что в каждой функции в JavaScript (исключая функции стрелок ) есть специальный arguments объект содержит аргументы, с которыми была вызвана функция, поэтому, поскольку вы передали soundFileName в качестве 3-го аргумента loop, переданное значение будет также доступно в loop как arguments[2], и поскольку оно было передано в качестве 1-гоаргумент getSound также будет доступенithin getSound как arguments[0].

0 голосов
/ 24 февраля 2019

Возможно, попробуйте изменить

 function loop() {

на:

function loop(param1,param2.....){

В вашем случае:

function loop(soundFileName,playDuration, ...){
...