如何使用长参数列表保持 javascript 代码简单和有条理?

How to keep javascript code simple and organized with long argument lists?

如果我使用的术语不准确,我深表歉意。我是新手。

我有一长串变量正在被函数 loop() shared/used。我目前只调用 loop() 两次,并且只传递声音文件的唯一参数 link。我将扩大这段代码的规模,以便对 loop() 进行多次调用,但每个调用都有一组独特的参数来替换我长长的共享变量列表。我认为每次调用 loop() 时都有一长串独特的参数会有点混乱和混乱。有没有一种方法可以通过制作不同的变量列表来保持内容的可读性和组织性,这些变量列表只能由特定调用 loop() 的参数访问?像这样的伪代码:

argumentListA {
    var sound = 'audio/sample.mp3'
    var aStartMin = 2
    var aStartMax = 200
    var seekMin = .5
    var seekMax = 2
    }

argumentListB {
    var sound = 'audio/sampleB.mp3'        
    var aStartMin = 0
    var aStartMax = 100
    var seekMin = 0
    var seekMax = 1
    }  

loop(argumentListA);
loop(argumentListB);

我希望能够在一个地方定义所有这些 variables/parameters,然后通过函数调用以一种简单的方式引用它们。

更新了以下工作代码:

<!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>
        var options = {
        soundFileName: 'audio/sample.mp3',
        aStartMin: 0,
        aStartMax: 100,
        probablilityAMin: 0,
        probablilityAMax: 10,
        probabilityThreshold: 3,
        seekMin: 0,
        seekMax: 1,
        aFadeIn: 9000,
        aFadeOut: 3000,
        aPlayDurationMin: 5000,
        aPlayDurationMax: 11000,
        maxVolume: 1,
        numberOfSounds: 0, // starting variable at 0 
        maxNumberOfSounds: 2
    };

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

    // calls the soundSorter function repeatedly so sounds will play

    (function masterClock(options) {
        setTimeout(function () {
            soundSorter();
            masterClock();
        }, 2000);
    }());

    function soundSorter() { // passing options into this before is what broke code
        var probabilityResult = Math.floor((Math.random() * options.probablilityAMax) + options.probablilityAMin);
        if (probabilityResult > options.probabilityThreshold) {
            loop(options);
        }
        else {
            loop(options);
        }
    }

    function loop(options) {

        setTimeout(function () {

            var playDuration = Math.floor((Math.random() * options.aPlayDurationMax) + options.aPlayDurationMin);

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

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

                    logNumberOfSounds();
                    console.log('probabilityThreshold is now: ' + options.probabilityThreshold);

                    //sound.volume(0); // don't think I need this since it's defined next as well as in getSound()
                    sound.fade(0, options.maxVolume, options.aFadeIn, id2); // FADE IN

                    setTimeout(function () {
                        sound.fade(options.maxVolume, 0, options.aFadeOut, id2); // FADE OUT
                        options.numberOfSounds--; //when it fades out subtract one

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

    // PLAYER FOR MAIN SOUND FUNCTION /////////////////////////////
    function getSound() {
        return new Howl({
            src: [options.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>

是的,像这样的东西作为选项对象传递是很常见的。

function loop(options) {
  // use options.sound, options.aStartMin, etc
}

如果需要,您可以单独存储选项对象:

var options1 = {
  sound: 'audio/sample.mp3',
  aStartMin: 2,
  aStartMax: 200,
  seekMin: .5,
  seekMax: 2
}

事实上,这很常见(取决于您打算支持的浏览器,或您的 babel 转译水平)现在支持称为 'object destructuring' 的东西,这使得这更容易:

function loop({ sound, aStartMin, aStartMax, etc }) {
  // Can now use sound, aStartMin, aStartMax, etc as if they were plain arguments.
}

使用对象进行解构赋值的其他好处是:

  1. 值按名称而不是顺序传递(对象属性无论如何都没有顺序)
  2. 并非所有(或任何)值都需要使用
  3. 如果 属性 缺失,它将作为 undefined
  4. 传递
  5. 您仍然可以在声明中设置默认值

// Define 3 properties on options object
var opts = {
  opt1: 'opt1 value',
  opt2: 'opt2 value',
  opt3: 'opt3 value'
};

// Use some option properties, even not defined props
function myFunc({opt3, opt1, foo, bar = 'bar'}) {
  console.log(`opt1: ${opt1}\nopt3: ${opt3}\nfoo : ${foo}\nbar : ${bar}`);
}

myFunc(opts);