通过重新分配使对象属性不可更改,但可在JavaScript中对其进行修改

时间:2019-03-29 00:39:29

标签: javascript properties getter-setter unmodifiable

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;
}

我有一个此类,定义了玩家角色的状态。我想通过重新分配使experienceObtainedgold属性不变,但可以通过运算符进行修改,以避免用户使用控制台为这些属性设置自己的值。

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

如上所示,我尝试使用未声明setter的getter,但仍可以通过控制台为amount分配任何值。

我不知道我是否误解了JavaScript中对getter和setter的使用,或者是否做不到。

1 个答案:

答案 0 :(得分:0)

  

避免用户使用控制台为这些属性设置自己的值。

最简单的方法就是防止从顶层访问Hero实例-例如,将所有内容包装在IIFE中:

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

然后,您在IIFE内进行的所有操作名义上都是私有的-用户将无法进入控制台并引用和更改他们想要的内容。 (不过,由于他们的浏览器,他们可以用其他方式做到这一点,例如使用用户脚本-您不能相信在客户端计算机上运行的任何内容都可以合法完成。)

使用类似的方法,依靠闭包的名义隐私,您可以使amount成为闭包变量的吸气剂,而无需使用setter,确保amount不能从外部更改(除非,当然,源代码也会被更改,在这种情况下,所有投注都将关闭)

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);