是否可以将参数名称作为字符串形式的参数传递,以用作函数中的参数名称?

时间:2019-03-29 06:04:42

标签: javascript string object variables parameters

在传递对象以及特定对象参数作为参数的过程中,我对同一个函数进行了多次调用。我没有问题单独传递对象或以object.param的形式传递对象参数。但是,我也想将对象名称和参数名称作为单独的参数传递,以便可以在函数中自由组合它们。但是,我无法弄清楚语法(或者是否支持我的想法)。

主要问题是我的语法是否正确:foo(param)this[objectName].param

我下面的简单示例似乎可以在playcode.io上使用,但是相同的原理在我的主要代码中不起作用。

这是代码的简单版本:

var options = {
  bar: 0
};

foo('bar'); // parameter name as string

function foo(param) {
  var objectName = "options";
  this[objectName].param = 2; // assembling object name with parameter name as string here
  console.log('param = ' + this[objectName].param)
}

更新:以下是使用@CertainPerformance的工作代码示例,建议不要使用.this

const optionNames = {
  optionsA: {
    startMin: 3
  },
  // other option names
};
const constObjectNames = {
  optionsConstA: {
    maxVolume: 1
    // etc
  }
  // other const object names
};

var objectName = "optionsA";
var constObjectName = "optionsConstA";

function callCalculateNewValue(optionName, constOptionName) {
  var param = optionName;
  return param;
}

foo('startMin');

function foo(param) {
  optionNames[objectName][param] = callCalculateNewValue(optionNames[objectName][param], constObjectNames[constObjectName]);
  console.log('= ' + optionNames[objectName][param]);
}

这是我用于上下文的实际代码。这个名字可笑的函数callCallCalculateNewValue是一个有疑问的函数:

function getRandom(min, max) { // returns a random number between min and max (both included)
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function valBetween(v, min, max) { // current value, min/max that I want to make sure v doesn't go under/over
    return (Math.min(max, Math.max(min, v)));
}

var optionsConstA = {
    // not recalculating each stage
    soundFileName: 'audio/60.wav',
    maxVolume: 1,
    startMinSeparation: 1000,       // the minimum distance appart the min/max values can be
    slaveStatusMin: 'master',
    minSeparation: 1000,
    // recalculating each stage
    startMin: 1050,                 // min time function waits before a sound is played
    startMax: 8000,                 // max time function waits before a sound is played
    playDurationMin: 15000,         // min play time for each sound 
    playDurationMax: 20000,         // max play time for each sound 
    fadeInMin: 10,                  // for individual sounds
    fadeInMax: 8000,                // for individual sounds
    fadeOutMin: 8000,               // for individual sounds
    fadeOutMax: 8000,               // for individual sounds
    chanceRandomMin: 90,            // values below the result won't be random, so for less chance variables are random, make min/max high
    chanceRandomMax: 99,            // values below the result won't be random
    rampMin: 0,
    rampMax: 4,
    rampVolumeMin: 0,               // number of stages the sounds will be faded in (total volume at each stage will be reduced by a percentage)
    rampVolumeMax: 4,
    volatilityMin: 1,              // result is multiplied by CalculatedChange. @@ This should possibly be unique for each parameter pair, though it is now calculating randomly within these values. 
    volatilityMax: 1              // result is multiplied by CalculatedChange
};

var optionsA = {
    startMin: 0,
    startMax: 0
};

function calculateNewValue(oldValue, min, max, volatilityMin, volatilityMax, slaveStatus, chanceRandomMin, chanceRandomMax, minSeparation, newMasterValue) {
    var randomThreshold = getRandom(chanceRandomMin, chanceRandomMax);                      
    var randomValue = getRandom(0, 100);                                                    // random number used against the threshold to see if the paramater should be reandomly determined
    console.log("random value: " + randomValue)                                             // the random number between 0-100 that if > the threshold value, it will use the random function 
    if (randomValue > randomThreshold || oldValue == 0) {                                   // if random = yes OR if the oldValue is 0 (which would mean that it's the very first tiem the function is being called and this will keep it from getting stuck near the Min value to start) parameter is determined randomly
        newValue = getRandom(min, max);                                                     // yes, it's random, so move randomly not incrementally from old value
        console.log('Was random: ' + newValue)
    }
    else {                                                                                  // if not random, determine its move from oldValue
        var changeLimit = (max - min) * .1;                                                 // @@ I'm setting the max possible incremental move at a pecentage (e.g., 10%) of difference betten max and min value. I can make this more detailed per parameter later. Maybe send a percentage artument along.
        var calculatedChange = getRandom(-changeLimit, changeLimit);                        // determines base value for parameter change (aka, change from oldValue)
        console.log('Calculated change: ' + calculatedChange)
        var volatility = getRandom(volatilityMin, volatilityMax);                           // @ I should refine volatility's relationship with calculatedChange
        newValue = valBetween(oldValue + (calculatedChange * volatility), min, max);        // make sure calculatedChange can be negative
    }
    if (slaveStatus == 'master') {
        newValue = valBetween(newValue, min, max - minSeparation);                          // if master (aka Min value), make sure Min is not so large that it doesn't have room for minSeparation (if it is added to Max)
    }
    if (slaveStatus !== 'master') {                                                         // now that the the value is determined, if you are a slave (aka a Max value which goes second), make sure you are >= to your master
        if (newValue < newMasterValue) {                                                    // if newValue is less than the calculated value of its min/max counterpart...
            newValue = newMasterValue;
        }
        if (newValue - newMasterValue < minSeparation) {                                    // i.e, there isn't enough separation between the Max value and the newly defined Min Value
            newValue = newValue + (minSeparation - (newValue - newMasterValue));            // adds needed separation value
            console.log('Max: Separation added')
        }
    }
    return newValue;
}

function callCalculateNewValue(objectName, constObjectName) {
    objectName = calculateNewValue(constObjectName.startMin, constObjectName.startMin, constObjectName.startMax, constObjectName.volatilityMin, constObjectName.volatilityMax, constObjectName.slaveStatusMin, constObjectName.chanceRandomMin, constObjectName.chanceRandomMax, constObjectName.minSeparation);
    return objectName;
}

var masterLoopStage = 0;

var calc = (function masterLoop(i) {
    setTimeout(function () {
        ++i;
        masterLoopStage = i; 
        console.log('masterLoopStage is: ' + i);

        callCallCalculateNewValue('startMin');
        function callCallCalculateNewValue(param) {
            var objectName = "optionsA";
            var constObjectName = "optionsConstA";
            this[objectName].param = callCalculateNewValue(this[objectName].param, this[constObjectName]);
            console.log('optionsA.startMin: ' + this[objectName].param)
        }

        optionsA.startMax = calculateNewValue(optionsA.startMax, optionsConstA.startMin, optionsConstA.startMax, optionsConstA.volatilityMin, optionsConstA.volatilityMax, optionsConstA.startMin, optionsConstA.chanceRandomMin, optionsConstA.chanceRandomMax, optionsConstA.minSeparation, optionsA.startMin);
        console.log('Min: ' + optionsA.startMin);
        console.log('Max: ' + optionsA.startMax);
        console.log('______________');
        /////////////////
        masterLoop(i);
    }, 3000)                                                                                //  time between increments
})(1);

console.log('____________');
console.log('Min: ' + optionsA.startMin);
console.log('Max: ' + optionsA.startMax);

1 个答案:

答案 0 :(得分:1)

在当前设置下,没有eval是不可能的,不应该使用它-但是,如果更改数据结构,使得可以成为objectName的所有内容都是而不是独立变量(对于动态constObjectName也是这样),而不是较大的对象的一个属性,这是可行的。例如:

const optionNames = {
  optionsA: {
    startMin: 0,
    startMax: 0
  },
  // other option names
};
const constObjectNames = {
  optionsConstA: {
    soundFileName: 'audio/60.wav',
    maxVolume: 1,
    // etc
  }
  // other const object names
};

然后,您可以使用普通括号表示法,就像第一个代码段中的foo函数一样。您的param还包含一个 string ,这是您要访问的属性名称,因此在使用param时也需要使用括号表示法,例如[param].param。全部:

const optionNames = {
  optionsA: {
    startMin: 1,
  },
  // other option names
};
const constObjectNames = {
  optionsConstA: {
    startMinB: 1,
  }
  // other const object names
};


function calculate(optionName, constOptionName) {
  var value = optionName + constOptionName.startMinB;
  return value;
}

foo('startMin'); // I'm still not sure what the syntax is for passing parameter name, or if I can

function foo(param) {
  var objectName = "optionsA";
  var constObjectName = "optionsConstA";

  optionNames[objectName][param] = calculate(optionNames[objectName][param], constObjectNames[constObjectName]);

  console.log('= ' + optionNames[objectName][param])
}

仅当相关代码在最高级别上运行时,您才能使用this,这不是一个好主意(您会不必要地污染全局范围)。