JavaScript 类 - 使用 WeakMap 将变量设为私有,并在其他方法中仍然使用 "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 = []
}
}
但是,如果我使用 WeakMap,那么我可以再次将项目设为私有,只是在给出的示例中,它们没有像我期望的那样使用 "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
我正在看书"Learning JS DataStructs and Algorithms",书上说"items"是下面class中的public。
class Stack {
constructor(){
this.items = []
}
}
但是,如果我使用 WeakMap,那么我可以再次将项目设为私有,只是在给出的示例中,它们没有像我期望的那样使用 "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