关于 WeakMap 和私有变量的问题

在我目前正在阅读的书中,它通过下面的示例代码讨论了我们如何使用 WeakMap 来强制执行隐私。


const Car = (function() {

  const carProps = new WeakMap();

  class Car {

    constructor(make, model) {

      this.make = make;

      this.model = model;

      this._userGears = ["P", "N", "R", "D"];

      carProps.set(this, { userGear: this._userGears[0] });

    }

    get userGear() {

      return carProps.get(this).userGear;

    }

    set userGear(value) {

      if (this._userGears.indexOf(value) < 0)

        throw new Error(`Invalid gear: ${value}`);

      carProps.get(this).userGear = value;

    }

    shift(gear) {

      this.userGear = gear;

    }

  }

  return Car;

})();

我无法理解这样的代码如何真正使齿轮财产成为私有并且不允许从外部访问。


似乎通过使用


carProps.set(this, { userGear: this._userGears[0] });

我们正在隐藏 userGear 并将其设为私有,因此无法访问。


但是,当我使用


const car1 = new Car("Toyota", "Prius");

console.log(car1);

console.log(car1.userGear);

它向我展示了结果


Car {

  make: 'Toyota',

  model: 'Prius',

  _userGears: [ 'P', 'N', 'R', 'D' ] }

P

我不确定为什么我可以访问 userGear 并在此处假设无法访问的地方得到“P”而不是“未定义”。


可能我做错了什么或错误地理解了这个概念。


有人可以帮我理解 WeakMap 吗?


守着星空守着你
浏览 193回答 1
1回答

慕斯709654

userGear代码中显示的 getter 和 setter只是为了向您展示如何carProps在类内部的(私有)和外部作用域之间进行通信。该示例的重点是表明carProps无法访问该变量,除非通过故意公开的userGear方法。如果这些方法不存在,那么在构造函数中设置 WeakMap 之后,外部使用者Car将无法看到或使用它做任何事情,例如:const Car = (function() {&nbsp; const carProps = new WeakMap();&nbsp; class Car {&nbsp; &nbsp; constructor(make, model) {&nbsp; &nbsp; &nbsp; this.make = make;&nbsp; &nbsp; &nbsp; this.model = model;&nbsp; &nbsp; &nbsp; this._userGears = ["P", "N", "R", "D"];&nbsp; &nbsp; &nbsp; carProps.set(this, { userGear: this._userGears[0] });&nbsp; &nbsp; }&nbsp; &nbsp; shift(gear) {&nbsp; &nbsp; &nbsp; this.userGear = gear;&nbsp; &nbsp; }&nbsp; }&nbsp; return Car;})();const car = new Car('foo', 'bar');// at this point, at this level of scope,// there is no way for a user of "car" or "Car" to reference carPropsconsole.log(car.userGear);再举一个更有意义的例子,假设构造函数选择了一个类的用户必须猜测的随机数:const Game = (function() {&nbsp; const gameProps = new WeakMap();&nbsp; return class Game {&nbsp; &nbsp; constructor() {&nbsp; &nbsp; &nbsp; gameProps.set(this, { randomNum: Math.floor(Math.random() * 10) });&nbsp; &nbsp; }&nbsp; &nbsp; guess(num) {&nbsp; &nbsp; &nbsp; return gameProps.get(this).randomNum === num ? 'Win' : 'Lose';&nbsp; &nbsp; }&nbsp; }})();const game = new Game();// at this point, at this level of scope,// there is no way for a user of "Game" or "game" to reference gameProps// or to figure out the random number, without guessing multiple timesconsole.log(&nbsp; game.guess(1),&nbsp; game.guess(2),&nbsp; game.guess(3),&nbsp; game.guess(4),&nbsp; game.guess(5));有了上面的代码,调用者没有办法在Game不调用(故意暴露的方法).guess几次的情况下找出游戏的内部随机数。(除非Math.random事先得到猴子补丁......)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript