原文链接 : Private members in ES6 classes
本文已获得原作者Greg Reimer的授权
译文出自 : 掘金翻译计划
转自:https://juejin.im/entry/572c0b2d2e958a00667a081d?utm_source=gold-miner&utm_medium=readme&utm_campaign=github
译者 : XRene
校对者:narcotics726, jingkecn
创建一个 ES6 的类,然后给它一个私有变量。
最基础的方法:
class Foo {
constructor(x) {
this.x = x;
}
getX() {
return this.x;
}
}
但是其实,这样定义的 x 根本不是私有的,可以通过对象随意的进行访问。
一个同等级但是具有一些提示效果的解决方案,就是在变量名前面加上下划线:
class Foo {
constructor(x) {
this._x = x;
}
getX() {
return this._x;
}
}
但即便这样,变量 _x 依旧不是真正的私有变量。
进一步的,我们可以将 x 设置为不可枚举的,更好的隐藏它:
class Foo {
constructor(x) {
Object.defineProperty(this, 'x', {
value: x,
enumerable: false,
});
}
getX() {
return this.x;
}
}
但是,如果有人读了源代码,还是可以随意访问 x。
下面这个方法才能算真正的藏起来了 x,此时通过 new Foo().x 这种方式是无法访问到 x 的了:
class Foo {
constructor(x) {
this.getX = () => x;
}
}
但是这样的话,每一个类的实例都会包含这个函数的副本。这样不仅效率低,同时也与预期不符:这个变量本应在存在于原型上。
好无奈,只好放大招了:
const __ = new Map();
class Foo {
constructor(x) {
__.set(this, { x });
}
getX() {
var { x } = __.get(this);
return x;
}
}
这样方法的缺点就是可能会导致内存泄漏。
解决方案就是,换成WeakMap:
const __ = new WeakMap();
class Foo {
constructor(x) {
__.set(this, { x });
}
getX() {
var { x } = __.get(this);
return x;
}
}
好了!完美。