Q: How to create a reusable function with different variables in javascript I am working on a game using javascript/html. I have many buttons, all of them are using the same function but with different values inside them.
I have 32 buttons which means 32 functions, those functions do exactly the same thing, except that they use different variables/values.
I was thinking about using objects/arrays, and put a function inside an object then reuse it changing its variables but I dont know if thats possible, or if it's a good idea.
I am still new at this. Those buttons are used to "attack" a monster, each of them is different i.e. "stats/health/damage".
My buttons are called "attack1/attack2/" and functions "attack1/attack2". Everytime I want to add a monster, I copy whole function and change its values which is not hard, but considering I want to change damage formula I need to change all 32 functions which isn't what I want to do.
I already created an object where I store all monsters data using arrays. 
Lastly, I am not a native English speaker, sorry if you can't understand me. Let me know if there is any way I can help you understand it better.
Thanks
var monsterStats = {
killed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

hp: [10, 30, 70, 130, 190, 280, 380, 500, 700, 900, 1300, 1600, 2200, 2600,
3000, 4000, 5000, 7000, 9000, 12000, 15000, 18000, 22000, 28000, 34000, 40000,
48000, 570000, 65000, 72000, 80000, 88000],

maxHp: [10, 30, 70, 130, 190, 280, 380, 500, 700, 900, 1300, 1600, 2200,
2600, 3000, 4000, 5000, 7000, 9000, 12000, 15000, 18000, 22000, 28000, 34000,
40000, 48000, 570000, 65000, 72000, 80000, 88000],

def: [0, 2, 4, 6, 9, 13, 18, 25, 30, 38, 45, 53, 65, 75, 88, 95, 120, 140,
170, 200, 220, 250, 300, 400, 500, 700, 1000, 1200, 2000, 2500, 3000],

minDmg: [2, 2, 4, 6, 9, 13, 18, 25, 32, 40, 50, 60, 75, 86, 96, 105, 140,
160, 200, 230, 260, 290, 350, 420, 500, 900, 1200, 1700, 2500, 3200, 4500,
6000],

maxDmg: [3, 5, 7, 10, 14, 19, 23, 30, 37, 45, 58, 67, 80, 92, 100, 110,
160, 185, 215, 250, 275, 320, 380, 550, 700, 1200, 1500, 2200, 3000, 4000,
5500, 8000],

baseExp:[5, 10, 30, 50, 90, 140, 190, 260, 340, 450, 560, 700, 810, 940,
1060, 1200, 1600, 2150, 2600, 3400, 5000, 7000, 10000, 15000, 23000, 35000,
70000, 120000, 180000, 290000, 430000, 680000, 1000000]

};
function attack(number) {
if (monsterStats.hp[0] >= 1) {
    var damage = Math.floor(Math.random() * (maxdamage - mindamage + 1)) +
        mindamage;
    damage = Math.floor(damage - monsterStats.def[0] * 1.2);
    if (damage > 1) {
        monsterStats.hp[0] -= damage;
        document.getElementById("hp1").innerHTML = monsterStats.hp[0];
        Log("You deal " + damage + " <span style=\"color:blue\">damage</span>");
    } else Log("<span style=\"color:blue\">Enemy block your attack! </span>");
    var dmg = Math.floor(Math.random() * (monsterStats.maxDmg[0] - monsterStats.minDmg[0] + 1)) + monsterStats.minDmg[0];
    dmg = Math.floor(dmg - defense * 1.2);
    if (dmg > 1) {
        health = health - dmg;
        document.getElementById("health").innerHTML = health;
        Log("Enemy hit you for " + dmg + " <span style=\"color:red\">damage</span>");
    } else Log("<span style=\"color:green\">You blocked enemy attack! </span>");
    if (health < 1) {
        monsterStats.hp[0] = monsterStats.maxHp[0];
        health = maxhealth;
        document.getElementById("hp1").innerHTML = monsterStats.hp[0];
        document.getElementById("health").innerHTML = health;
        Log("<span style=\"color:blue\">You have lost!</span>");
    }
    if (monsterStats.hp[0] < 1) {
        monsterStats.killed[0] = monsterStats.killed[0] + 1;
        monsterStats.hp[0] = monsterStats.maxHp[0];
        document.getElementById("hp1").innerHTML = monsterStats.hp[0];
        document.getElementById("kills1").innerHTML = monsterStats.killed[0];
        var expgain = monsterStats.baseExp[0] / (level / 5);
        if (experience < maxexperience) {
            experience = Math.floor(experience + expgain);
            if (experience >= maxexperience) {
                level += 1;
                stats += 2;
                experience = experience - maxexperience;
                maxexperience = Math.floor(maxexperience * 1.2);
                Log("You leveled up! Your current level is: " + level);
                document.getElementById("maxexperience").innerHTML = maxexperience;
                document.getElementById("level").innerHTML = level;
                document.getElementById("stats").innerHTML = stats;
                document.getElementById("experience").innerHTML = experience;
            } else Log("You gain: " + Math.floor(expgain) + "experience!");
            document.getElementById("experience").innerHTML = experience;
        }
        var goldLog = 0;
        var golddrop = Math.floor((Math.random() * 100) + 1);
        if (golddrop > 95) {
            golddrop = Math.floor((Math.random() * 20) + 1);
            gold = gold + golddrop;
            Log("You loot: " + golddrop + "gold!");
            document.getElementById("gold").innerHTML = gold;
        } else if (golddrop >= 75) {
            golddrop = Math.floor((Math.random() * 10) + 1);
            gold = gold + golddrop;
            Log("You loot: " + golddrop + "gold!");
            document.getElementById("gold").innerHTML = gold;
        } else if (golddrop >= 60) {
            golddrop = Math.floor((Math.random() * 5) + 1);
            gold = gold + golddrop;
            Log("You loot: " + golddrop + "gold!");
            document.getElementById("gold").innerHTML = gold;
        }
        "This is <span style=\"color:red\">RED</span> text.";
        var itemdrop = Math.floor((Math.random() * 100) + 1);
        if (itemdrop < 33) {
            var fusiondrop = Math.floor((Math.random() * 100) + 1);
            if (fusiondrop < 70) {
                common = common + 1;
                Log("You loot:<span style=\"color:grey\">Common</span> Fusion stone!");
                document.getElementById("common").innerHTML = common;
            } else if (fusiondrop <= 100) {
                rare = rare + 1;
                Log("You loot:<span style=\"color:blue\">Rare</span> Fusion stone!");
                document.getElementById("rare").innerHTML = rare;
            }
        } else if (itemdrop < 66) {
            var expdrop = Math.floor((Math.random() * 100) + 1);
            if (expdrop < 70) {
                commonexp = commonexp + 1;
                Log("You loot:<span style=\"color:grey\">Common</span> Exp orb!");
                document.getElementById("commonexp").innerHTML = commonexp;
            } else if (expdrop <= 100) {
                rareexp = rareexp + 1;
                Log("You loot:<span style=\"color:blue\">Rare</span> Exp orb!");
                document.getElementById("rareexp").innerHTML = rareexp;
            }
        } else {
            var golddrop = Math.floor((Math.random() * 100) + 1);
            if (golddrop < 70) {
                commongold = commongold + 1;
                Log("You loot:<span style=\"color:grey\">Common</span> Gold orb!");
                document.getElementById("commongold").innerHTML = commongold;
            } else if (golddrop <= 100) {
                raregold = raregold + 1;
                Log("You loot:<span style=\"color:blue\">Rare</span> Gold orb!");
                document.getElementById("raregold").innerHTML = raregold;
            }
        }
    }
}

}
Thats a part of the code, I use this code 32 times.

A: I think you're looking for something like this:
function createAttack1(damage) {
    return function() {
        ... Your attack1 logic using 'damage'
    }
}

Then you can use this to hook up your buttons:
button1.addEventListener("click", createAttack1(5));
button2.addEventListener("click", createAttack1(10));
button3.addEventListener("click", createAttack1(15));

This allows you to reuse the same core logic, while having different stats without all the copy/paste you've been doing.

A: Let say you create an array of Monster "objects" like this:
var Monsters = {
    "foo": {"name":"Foo the foot", "hp":125, "power":3},
    "bar": {"name":"Barbarian the bar", "hp":25, "power":9001}
};

You may as well write your button markup so each one can be related to one monster. For example:
<button rel="attack" data-monster_id="foo">Attack</button>
<button rel="attack" data-monster_id="bar">Attack</button>

Now, you may link them with something like that:
var btns = document.querySelectorAll('button[rel="attack"]');
for (var i=0; i<btns.length; i++) {
    this.addEventListener('click', function(){
        attack(this.dataset.monster_id);
    }, false);
}

Finally, let assume an attack method that would go like this:
function attack(id) {
    Monsters[id].hp -= currentDamage;
    // whatever consequences the attack may have
}

Hope this gives you the idea and good luck with your game :)

A: Not sure what you mean, but I think using event delegation may help to reuse a function. In the snippet example, a data-* attribute is used to store a score with a button. Furthermore event delegation enables you to create new buttons without having to assign new handlers.


document.querySelector('#testbuttons').addEventListener('click', testdemo);
document.querySelector('#testcreate').addEventListener('click', newbttn);

// handler for all buttons within div#testbutton
function testdemo(e) {
  var from = e.target || e.srcElement
     ,score = from.getAttribute('data-score')
     ,kills = JSON.parse(from.getAttribute('data-kills'));
  if (!score) { return true; }
  Helpers.log2Screen('score clicked button: ', score, 
                     ', kills: <code>[', kills, ']</code>',
                      {clear: true});
}

function newbttn() {
  var score = Math.floor(1+Math.random()*200);
  document.querySelector('#testbuttons').innerHTML +=
    '<br><button data-score="'+score+'" data-kills="[]">button '+score+'</button>';
  Helpers.log2Screen('Created new button with score ', score, {clear: true});
}
button {
  margin-top: 3px;
}
<!-- a few helpers -->
<script src="http://kooiinc.github.io/JSHelpers/Helpers-min.js"></script>

<div id="result"><p>Awaiting action ...</p></div>
<div id="testbuttons">
  <button data-score="12" data-kills="[2,5,3]">bttn 12</button><br>
  <button data-score="122" data-kills="[0,2,8]">bttn 122</button>
</div>

<button id="testcreate">create new button</button>


