简体   繁体   中英

Making an object property unchangeable through reassignment but modifiable in JavaScript

class Hero extends Character {
constructor (name, race, gender, role, level){
    super(name, race, gender, role, level);
    this.inventory = [];
    this.experience = {
        experienceNeeded: 100,
        experienceObtained: 0
    };
    this.gold = 0;
}

I have this class which defines how a player Character will be. I want to make both experienceObtained and gold properties unchangeable through reassignment but modifiable through operators to avoid users set their own values to these properties using console.

this.gold = {
        amount: 0,
        get gold(){
            return this.amount;
        }
    };

As showed above I tried using a getter without declaring a setter but I still can assign amount any value through console.

I don't know if I am misunderstanding the use of getters and setters in JavaScript or if it is not possible to do.

to avoid users set their own values to these properties using console.

The easiest way to do this would simply be to prevent a Hero instance from being accessible from the top level - for example, wrap everything in an IIFE:

(() => {
  const hero = new Hero();
  // do stuff with hero
})();

Then, everything you do inside the IIFE will be nominally private - a user wouldn't be able to go into the console and reference and change what they want. (Still, since it is their browser, they could do it other ways, such as with a userscript - you can't trust anything that runs on the client's machine to be done legitimately.)

Using a similar method, relying on the nominal privacy of a closure, you can make amount a getter of a closure variable without a setter, ensuring that amount is not changeable from the outside (unless, of course, the source code is altered, in which case all bets are off anyway):

 const Hero = (() => { const privateHeroGold = new WeakMap(); return class Hero { constructor() { privateHeroGold.set(this, 0); } get gold() { return privateHeroGold.get(this); } set gold(g) { console.log("You're not allowed to do that!"); } } })(); const hero = new Hero(); console.log(hero.gold); hero.gold = 5; console.log(hero.gold); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM