JavaScript 类 - 使用 Wea​​kMap 将变量设为私有,并在其他方法中仍然使用 "this"

JavaScript Classes - Making variables private with WeakMap and still using "this" in other methods

我正在看书"Learning JS DataStructs and Algorithms",书上说"items"是下面class中的public。

class Stack {
    constructor(){
      this.items = []
    }
 }

但是,如果我使用 Wea​​kMap,那么我可以再次将项目设为私有,只是在给出的示例中,它们没有像我期望的那样使用 "this"。

const items = new WeakMap();
class Stack {
    constructor(){
      items.set(this, []);
    }
}

然后它给出了一些代码示例,这些代码可以执行 items.set 或 items.get 之类的操作来访问内容,这看起来不错,但我想知道我是否可以缩短对 item.get(value) 在构造函数中放到 "this" 上,像这样:

const items = new WeakMap();
class Stack {
    constructor() {
        items.set(this, []);
        this.stack = items.get(this, []);

     push(item) {
         this.stack.push(item)
     }
}

现在,我可以使用 this.stack 访问 items.get() 功能,但我不确定它是否会再次 public,并且想知道是否有人可以帮助清除适合我吗?

是 - this 的任何 属性 实际上都是 public。因此,如果您有 this.stack,并且 stack 指的是一个数组,那么该数组将可以从任何可以访问实例化对象的对象中查看和更改,这可能是您不想要的。

请注意,即使在第二个代码片段中,使用 items WeakMap 也不足以使数据 private - 例如,任何可以访问 items 和实例化对象的东西都可以更改该项目的数组:

const items = new WeakMap();
class Stack {
  constructor() {
    items.set(this, []);
  }
}

const s = new Stack();
items.get(s).push('foo');
console.log(items.get(s));

要解决这个问题,一个选择是将整个东西放在一个 IIFE 中,items 范围 IIFE 中,然后 return class:

const Stack = (() => {
  const items = new WeakMap();
  return class Stack {
    constructor() {
      items.set(this, []);
    }
  };
})();
const s = new Stack();
// now, items can only be seen and modified through Stack's internal methods