原文鏈接 : 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;
}
}
好了!完美。