Come chiamare un valore di una proprietà di oggetti al di fuori del creatore di oggetti

Sto cercando di creare un’equazione per il danno del giocatore che usa la difesa dei mostri come calcolo. Dato che ogni mostro ha un diverso valore di difesa, non so come codificarlo per cambiare in base al mostro selezionato. Ecco cosa ho provato. JSFiddle

var playerGold = 0; var playerExp = 0; var playerLvl = 1; var expNeeded = 10; var playerHP = 10; var playerATK = 1; var playerDEF = 1; var playerSPD = 1; function Monster(name, exp, gold, hp, atk, def, spd) { this.name = name; this.exp = exp; this.gold = gold; this.hp = hp; this.atk = atk; this.def = def; this.spd = spd; // Method definition this.implement = function() { var monsterList = document.getElementById('monsterList'); var opt = document.createElement('OPTION'); // Creating option opt.innerText = this.name; // Setting innertText attribute monsterList.appendChild(opt); // appending option to select element } var playerDam = function () { var playerDamage = Math.round(playerATK - this.def); } // Method execution this.implement(); } var fly = new Monster("fly", 1, 1, 5, 1, 0, 1); var mouse = new Monster("mouse", 2, 3, 10, 2, 0, 2); var rat = new Monster("rat", 4, 5, 20, 4, 2, 2); var rabidChihuahua = new Monster("rabid chihuahua", 6, 8, 35, 6, 1, 4); var bulldog = new Monster("bulldog", 10, 14, 60, 10, 4, 1); $('#battleButton').click(function() { playerDam(); $('#dam').html("You have hit the " + $('#monsterList').val() + " for " + playerDamage + " damage"); }); 

Un modo per ottenere ciò che vuoi è:
– salva un riferimento a this nella class Monster (come self per esempio)
– salva un riferimento a ciascun object Monster in un attributo data dell’elemento option .

 function Monster(name, exp, gold, hp, atk, def, spd) { var self = this; /* ...*/ this.implement = function() { /* ... */ // we save the Monster object (self) in the //  data attribute 'monster' $(opt).data('monster', self) } // and your playerDam function becomes: this.playerDam = function () { self.playerDamage = Math.round(playerATK - this.def); return self.playerDamage; } } 

Quando l’utente fa clic sul pulsante, recuperi il valore selezionato corrente e ottieni l’attributo dei dati:

 monsterEl = $('#monsterList option:selected'); // we retrieve the monster selected from the  data attribute monster = monsterEl.data('monster') $('#dam') .html("You have hit the " + $('#monsterList').val() + " for " + monster.playerDam() + " damage"); 

Guarda il violino aggiornato

modificare

Hai una lista di mostri, se solo fai:

 var opt = document.createElement('OPTION'); // Creating option opt.innerText = this.name; 

Quindi non salvi il mostro, ma solo il nome del mostro.

Quindi devi mantenere un riferimento all’object mostro in ogni elemento option .

Un modo per farlo è usare gli data-attributes cui scopo è quello di memorizzare un object con un nome (qui ho scelto monster ma potrebbe essere qualsiasi stringa), che potresti recuperare in seguito.

Quando crei un nuovo mostro come var fly = new Monster("fly", 1, 1, 5, 1, 0, 1) , questo creerà un elemento (il mostro dei dati non verrà mostrato nella sorgente, ma credetemi, è lì), contenente l’object Monster con tutte le sue proprietà (nome, hp, exp …).

Quando fai clic sul pulsante, jQuery otterrà l’opzione selezionata e recupererà i dati con il monster principale:

 // get the selected option via CSS selector monsterEl = $('#monsterList option:selected') // get the associated Monster via the .data('monster') method monster = monsterEl.data('monster') // now you can invoke method on the monster variable console.log(monster.name ) // 'fly' console.log(monster.hp ) // 5 

Ora come per la funzione playerDam() :

 var self = this this.playerDamage = 0; this.playerDam = function () { self.playerDamage = Math.round(playerATK - self.def); return self.playerDamage; } 

Stai assegnando la funzione playerDam all’ambito della funzione Monster ( this ).
Per accedere allo scope di Monster all’interno della funzione, devi usare un trucco e usare una variabile (qui self , ma potrebbe essere qualsiasi nome di variabile) per archiviare in anticipo il scope di Monster. Quindi puoi accedervi dall’interno della funzione playerDam .

Potresti anche aver usato un metodo sul prototipo per risparmiare memoria:

 Monster.prototype.playerDam = function() { // 'this' is the now the Monster class scope this.playerDamage = Math.round(playerATK - this.def); return this.playerDamage; } 

Spero di essere stato chiaro, questo mixò molti concetti diversi insieme, forse altri potrebbero spiegarlo meglio di quello che ho fatto;) Dovresti dare un’occhiata al framework Javascript come Knockout , react o vue.js che ti rendono più facile !

Modifica 2
Ho reupdato il violino per sistemare this.def nella funzione this.def